From e42f815017e2ffeb094d55db2aa1ab0d02d84f2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Leite?= Date: Sat, 13 Jun 2026 20:53:00 -0300 Subject: [PATCH] chore: untrack OS-noise files, add CLAUDE.md, record 0.1.2 submission - Stop tracking .DS_Store and .Rhistory files (already in .gitignore; they were committed before being ignored, so git kept reporting them). - Add CLAUDE.md (repo guidance) and exclude it from the build via .Rbuildignore. - Record the 0.1.2 CRAN submission in CRAN-SUBMISSION (written by submit_cran(); SHA matches the v0.1.2 tag). Co-Authored-By: Claude Opus 4.8 (1M context) --- .DS_Store | Bin 8196 -> 0 bytes .Rbuildignore | 1 + .Rhistory | 281 --------------------------------------- CLAUDE.md | 76 +++++++++++ CRAN-SUBMISSION | 6 +- docs/.DS_Store | Bin 6148 -> 0 bytes docs/deps/.DS_Store | Bin 8196 -> 0 bytes docs/reference/.DS_Store | Bin 6148 -> 0 bytes inst/.DS_Store | Bin 6148 -> 0 bytes 9 files changed, 80 insertions(+), 284 deletions(-) delete mode 100644 .DS_Store delete mode 100644 .Rhistory create mode 100644 CLAUDE.md delete mode 100644 docs/.DS_Store delete mode 100644 docs/deps/.DS_Store delete mode 100644 docs/reference/.DS_Store delete mode 100644 inst/.DS_Store diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index 62998f5838bef864b8d580a62be4af7dc6816bfe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8196 zcmeHMJ!@1!6g~5@;>tE5ASPh(1WOUO5HW(hgtfCu8ap-FutsGdhxfQ|0jT+nb`zKeP-oY6 zvcaLGX}|7;7P*zvw2JxYcAAUJX|G?1lm$^h6c7bO0Z~8{_*WF*J6pGU#e3g+WfTQO zf&Wqg{d|bowN0GOtTm4g4yFX4t#R2j&L{PRHg+~~HnWx&Y6D9WI7|JZ~>CDzI)3Wx$l1$6CR!&!8&ieXT{r(Zt%zFyjDEp^i+ zuGOzc7vF!~{V*5$+Xwplx4dryTaTEE25}eA$2wBn=6nMKtYAH0fo#7z(&zN#4e*Y?V*rlwF5KZw)JopV;i~)3ixD~e&F>aJw@;2oMO45?z0rIW7J{>@%TMiU z4)@_Di_7>Nmggzi{|JUWX^L)mqkvOqh~s%fyliLI;sp`oyA6~@1o$|o&vy)Wd9yma zTPtKTv3>oz)!`H_dm6lCJG#$0uy%YXk6n^Yq2#?8m_i35Yn}F%zlGiHyxK*Yf?Dq5WQ~7aoW)zhMdRFmpGeQ SOAniT2rx3pAPW3Z1%3jV=^}^# diff --git a/.Rbuildignore b/.Rbuildignore index 89b4b32..cd5fb5e 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -15,5 +15,6 @@ ^cran-comments\.md$ ^CRAN-SUBMISSION$ ^\.claude$ +^CLAUDE\.md$ ^\.Rhistory$ ^\.positai$ diff --git a/.Rhistory b/.Rhistory deleted file mode 100644 index ec86f90..0000000 --- a/.Rhistory +++ /dev/null @@ -1,281 +0,0 @@ -pkgdown::build_site() -pkgdown::build_site() -library(jsonlite) -library(dplyr) -library(tibble) -library(lubridate) -# ── Sample data (57 employees) ──────────────────────────────────────────────── -json_url <- "https://raw.githubusercontent.com/StrategicProjects/DT2/main/inst/examples/employees.json" -# For offline use, the same JSON is bundled in inst/examples/employees.json -json_txt <- '{ -"data": [ -{"name":"Tiger Nixon","position":"System Architect","salary":"320800","start_date":"2011-04-25","office":"Edinburgh","extn":"5421"}, -{"name":"Garrett Winters","position":"Accountant","salary":"170750","start_date":"2011-07-25","office":"Tokyo","extn":"8422"}, -{"name":"Ashton Cox","position":"Junior Technical Author","salary":"86000","start_date":"2009-01-12","office":"San Francisco","extn":"1562"}, -{"name":"Cedric Kelly","position":"Senior JavaScript Developer","salary":"433060","start_date":"2012-03-29","office":"Edinburgh","extn":"6224"}, -{"name":"Airi Satou","position":"Accountant","salary":"162700","start_date":"2008-11-28","office":"Tokyo","extn":"5407"}, -{"name":"Brielle Williamson","position":"Integration Specialist","salary":"372000","start_date":"2012-12-02","office":"New York","extn":"4804"}, -{"name":"Herrod Chandler","position":"Sales Assistant","salary":"137500","start_date":"2012-08-06","office":"San Francisco","extn":"9608"}, -{"name":"Rhona Davidson","position":"Integration Specialist","salary":"327900","start_date":"2010-10-14","office":"Tokyo","extn":"6200"}, -{"name":"Colleen Hurst","position":"JavaScript Developer","salary":"205500","start_date":"2009-09-15","office":"San Francisco","extn":"2360"}, -{"name":"Sonya Frost","position":"Software Engineer","salary":"103600","start_date":"2008-12-13","office":"Edinburgh","extn":"1667"} -] -}' -df <- fromJSON(json_txt, flatten = TRUE)$data %>% -as_tibble() %>% -mutate( -salary = as.numeric(salary), -extn = as.integer(extn), -start_date = ymd(start_date) -) -# ── Shiny App ───────────────────────────────────────────────────────────────── -library(shiny) -library(bslib) -library(DT2) -library(htmlwidgets) -ui <- page_sidebar( -theme = bs_theme(version = 5, bootswatch = "spacelab"), -title = "DT2 — Complete Example", -sidebar = sidebar( -h5("Features"), -tags$ul( -tags$li("ColumnControl (order + search dropdowns)"), -tags$li("Export buttons with spacer"), -tags$li("Custom JS renderers"), -tags$li("pt-BR translation") -) -), -# Flag sprites -tags$head( -tags$link( -rel = "stylesheet", type = "text/css", -href = "https://cdn.jsdelivr.net/gh/lafeber/world-flags-sprite/stylesheets/flags32-both.css" -), -tags$style(HTML(" -.f32 .flag { display:inline-block; width:32px; height:32px; -vertical-align:middle; margin-right:6px; } -table.dataTable tbody td { vertical-align: middle; } -")) -), -card( -card_header("Employee Table"), -card_body(dt2_output("tbl", height = "auto")) -) -) -server <- function(input, output, session) { -output$tbl <- render_dt2({ -# ── JS Renderers ────────────────────────────────────────── -office_js <- JS(" -function(data, type) { -if (type !== 'display') return data; -var cc = {Argentina:'ar', Edinburgh:'_Scotland', London:'_England', -'New York':'us', 'San Francisco':'us', Sydney:'au', Tokyo:'jp'}; -var flag = cc[data] || ''; -return ' ' + data; -} -") -salary_js <- JS(" -(function() { -var nfmt = DataTable.render.number('.', ',', 2, 'R$ '); -return function(data, type) { -var txt = nfmt.display(data); -if (type !== 'display') return txt; -var c = data < 250000 ? 'red' : data < 500000 ? 'orange' : 'green'; -return '' + txt + ''; -}; -})() -") -extn_js <- JS(" -function(data, type) { -return type === 'display' -? '' -: data; -} -") -# ── Options ─────────────────────────────────────────────── -opts <- list( -pageLength = 10, -lengthMenu = c(10, 25, -1), -columns = names(df), -layout = list( -topStart = "pageLength", -topEnd = list( -buttons = list( -list(extend = "copyHtml5", text = "Copiar"), -list(extend = "csvHtml5"), -list(extend = "excelHtml5"), -list(extend = "spacer", style = "bar"), -list(extend = "colvis", text = "Colunas") -), -search = list(placeholder = "") -), -bottomEnd = "paging" -), -columnControl = list( -target = 0, -content = list("order", "searchDropdown", list( -list(extend = "orderAsc", text = "Ordem crescente"), -list(extend = "orderDesc", text = "Ordem decrescente"), -"spacer", -list(extend = "colVisDropdown", text = "Selecionar colunas") -)) -), -ordering = list(indicators = FALSE, handler = FALSE), -columnDefs = list( -list(targets = which(names(df) == "office") - 1L, -className = "f32", render = office_js), -list(targets = which(names(df) == "salary") - 1L, -className = "dt-body-right", render = salary_js), -list(targets = which(names(df) == "extn") - 1L, -render = extn_js) -), -language = list( -lengthMenu = "Mostrar _MENU_", -search = "Buscar", -info = "Mostrando _START_ a _END_ de _TOTAL_ registros", -infoEmpty = "Nenhum registro", -zeroRecords = "Nenhum registro encontrado", -emptyTable = "Nenhum dado disponível", -decimal = ",", thousands = ".", infoThousands = ".", -lengthLabels = list(`10` = "10", `25` = "25", `-1` = "Todas"), -paginate = list(first="«", previous="‹", `next`="›", last="»"), -buttons = list( -copyTitle = "Copiado!", -copySuccess = list(`_` = "%d linhas copiadas", `1` = "1 linha copiada") -), -columnControl = list( -orderAsc = "Crescente", orderDesc = "Decrescente", -searchDropdown = "Pesquisar", colVisDropdown = "Colunas", -searchClear = "Limpar", -search = list( -text = list(contains="Contém", starts="Começa por", -ends="Termina em", equal="Igual a"), -number = list(greater="Maior que", less="Menor que", -equal="Igual a") -) -) -) -) -dt2(df, -compact = TRUE, striped = TRUE, hover = TRUE, -font_scale = 0.85, responsive = FALSE, -options = opts) -}) -} -shinyApp(ui, server) -library(shiny) -library(bslib) -library(DT2) -ui <- page_fillable( -theme = bs_theme(version = 5, bootswatch = "flatly"), -padding = "1rem", -layout_columns( -col_widths = c(6, 6), -card( -card_header("simple (prev / next only)"), -card_body(dt2_output("tbl_simple")) -), -card( -card_header("full_numbers (first / 1 2 3 / last)"), -card_body(dt2_output("tbl_full")) -) -), -card( -card_header("No pagination"), -card_body(dt2_output("tbl_none")) -) -) -server <- function(input, output, session) { -output$tbl_simple <- render_dt2({ -dt2(iris, options = list(pageLength = 5, pagingType = "simple")) -}) -output$tbl_full <- render_dt2({ -dt2(iris, options = list(pageLength = 5, pagingType = "full_numbers")) -}) -output$tbl_none <- render_dt2({ -dt2(iris[1:15, ], options = list(paging = FALSE)) -}) -} -shinyApp(ui, server) -pkgdown::build_site() -pkgdown::build_site() -pkgdown::build_site() -pkgdown::build_site_github_pages() -pkgdown::build_site_github_pages() -pkgdown::build_site_github_pages() -pkgdown::build_site_github_pages() -pkgdown::build_site_github_pages() -pkgdown::build_site_github_pages() -usethis::use_cran_comments() -pkgdown::build_site_github_pages() -lang_ptbr <- list( -# ── Core table ────────────────────────────────────────────── -lengthMenu = "Mostrar _MENU_", -search = "Buscar", -info = "Mostrando _START_ a _END_ de _TOTAL_ registros", -infoEmpty = "Mostrando 0 a 0 de 0 registros", -infoFiltered = "(filtrado de _MAX_ registros no total)", -zeroRecords = "Nenhum registro encontrado", -emptyTable = "Nenhum dado disponível", -loadingRecords = "Carregando dados...", -decimal = ",", -thousands = ".", -infoThousands = ".", -paginate = list( -first = "«", previous = "‹", `next` = "›", last = "»" -), -# Rótulos do menu "entries per page" -# (mapeia o valor numérico → texto exibido no select) -lengthLabels = list( -`10` = "10", `25` = "25", `50` = "50", `-1` = "Todas" -), -# ── Buttons extension ────────────────────────────────────── -buttons = list( -copyTitle = "Copiado para a área de transferência", -copyKeys = paste0( -"Pressione Ctrl ou \u2318 + C para copiar. ", -"Pressione Esc para cancelar." -), -copySuccess = list(`_` = "%d linhas copiadas", `1` = "1 linha copiada") -), -# ── ColumnControl extension ──────────────────────────────── -columnControl = list( -colVis = "Visibilidade da coluna", -colVisDropdown = "Visibilidade da coluna", -dropdown = "Mostrar mais...", -orderAsc = "Ordem crescente", -orderDesc = "Ordem decrescente", -orderClear = "Remover ordenação", -orderRemove = "Remover ordenação", -searchClear = "Limpar pesquisa", -searchDropdown = "Pesquisar", -reorder = "Reordenar", -reorderLeft = "Mover para a esquerda", -reorderRight = "Mover para a direita", -list = list( -all = "Todos", empty = "Vazio", none = "Nenhum", -search = "Pesquisar..." -), -search = list( -text = list( -contains = "Contém", empty = "Vazio", ends = "Termina em", -equal = "Igual a", notContains = "Não contém", -notEmpty = "Não está vazio", notEqual = "Diferente de", -starts = "Começa por" -), -number = list( -empty = "Vazio", equal = "Igual a", -greater = "Maior que", greaterOrEqual = "Maior ou igual a", -less = "Menor que", lessOrEqual = "Menor ou igual a", -notEmpty = "Não está vazio", notEqual = "Diferente de" -), -datetime = list( -empty = "Vazio", equal = "Igual a", -greater = "Posterior a", less = "Anterior a", -notEmpty = "Não está vazio", notEqual = "Diferente de" -) -) -) -) -# Use it -dt2(iris, options = list(pageLength = 10, language = lang_ptbr)) diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..8e41a46 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,76 @@ +# CLAUDE.md + +Guidance for working in the **DT2** repository. + +## What this package is + +DT2 is an `htmlwidgets` binding for **DataTables v2** (the JS library by SpryMedia). +It configures DataTables via plain R lists (1:1 with the JS API), with modular +extension loading, Bootstrap 5 styling, and Shiny integration (proxy, events, +inline inputs, server-side processing). Written from scratch for the v2 API — +not a fork of the `DT` package. + +- R code: `R/` · JS runtime: `inst/htmlwidgets/dt2.js` · bundled libs: `inst/htmlwidgets/lib/` +- Vignettes: `vignettes/` · built site: `docs/` (gitignored, see below) + +## Common commands + +```r +# load for interactive dev / run a quick check +pkgload::load_all(".") + +# regenerate Rd from roxygen (package uses roxygen2 8 — Config/roxygen2/version) +roxygen2::roxygenise() + +# tests (testthat edition 3) +testthat::test_dir("tests/testthat") + +# full check (clean: 0/0/0) +devtools::check(args = "--as-cran") + +# CRAN pre-submission (results emailed to maintainer) +devtools::check_win_devel(); devtools::check_win_release() +``` + +## Conventions / gotchas + +- **roxygen2 8**: version is recorded in `Config/roxygen2/version` (no `RoxygenNote`). + Run `roxygenise()` after changing any `#'` block. Build with the system R + (`Rscript`/`R CMD`), which is R 4.6 here. +- **`options$columns` is the name→index map.** Name-based helpers + (`dt2_cols_*`, `dt2_format_*`, `dt2_order`, ...) resolve names against + `options$columns`. The user must set `opts <- list(columns = names(df))` + *before* calling them; `dt2()` injects it from the data, but that runs after + the helpers. Resolution is centralized in `.dt2_name_to_idx()` (`R/dt2_utils.R`), + which **warns** on unresolved names instead of returning silent `NA`. +- **Generated JS must be quote-safe.** Use `.dt2_js_str()` (jsonlite) to build + JS string literals, never `sprintf("'%s'", x)`. +- **SSP query strings:** `dt2.js` encodes query-string *keys* with + `encodeURIComponent`, so the server parser (`.dt2_parse_ssp_request`) must + URL-decode keys, not just values. +- **CRAN is live:** DT2 is on CRAN. Public API is frozen — do not remove + exported functions; cross-link/deprecate instead. + +## pkgdown site (`docs/`) + +- The site theme uses **`tidytemplate`** (NOT on CRAN). Install before building: + `pak::pak("tidyverse/tidytemplate")`. +- `docs/` is in `.gitignore` but the tracked site is **force-committed**. To + rebuild and commit: + 1. `R CMD INSTALL .` then `pkgdown::build_site(install = FALSE)` + 2. delete orphaned versioned asset dirs (old `dt2-binding-*`, old `bootstrap-*`) + 3. `git add -f docs/`, then unstage every `.DS_Store` +- `_pkgdown.yml` has a curated grouped `reference:` index — keep it in sync with + `NAMESPACE` exports (every export must appear exactly once or pkgdown errors). + +## Release flow (followed for 0.1.2) + +Bump `DESCRIPTION` Version+Date → update `NEWS.md` → update `cran-comments.md` +→ `check(--as-cran)` + win-builder devel/release → rebuild site → publish GitHub +release/tag `vX.Y.Z` (`gh release ...`) → `devtools::submit_cran()` (maintainer +runs this; CRAN confirmation is emailed). + +## House rules in this repo + +- Never stage `.DS_Store` or `.Rhistory` (they show as modified but are noise). +- Branch per change + PR + merge; reference issues with `Closes #N`. diff --git a/CRAN-SUBMISSION b/CRAN-SUBMISSION index 4cc83fa..f5454d8 100644 --- a/CRAN-SUBMISSION +++ b/CRAN-SUBMISSION @@ -1,3 +1,3 @@ -Version: 0.1.1 -Date: 2026-04-29 17:40:56 UTC -SHA: da1c22281b59b3c8d60f33abb4cc1de8a5284390 +Version: 0.1.2 +Date: 2026-06-13 23:44:56 UTC +SHA: ee47dc3fb6b625f3416a23e6c9e0a302f4591fb2 diff --git a/docs/.DS_Store b/docs/.DS_Store deleted file mode 100644 index dde525457957cda1f45178472379499ab4529618..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHKy-EW?5T4Z_i8et56`OkkA-%;JE?|F+SZRLLK#~h;u(3G7+6PD>c7ktUYhx?u zD`@Eh2%_KYZtlmdK^qa7f!XhFXJ%*iySv?6B2v{svqDrRq9T;BFpI_^Y-b&lDciFE zRCT52aZWILdPE=>x z&F0I-)9u~5+pqa8zy5wDOmc=XhN1#Bv6}SFdNQ(6cz>O>W$So<7@j_xI+ECKl;(HY zvw3NY(;{yVd5=Hk)uz;z%{w!Hx%hUa=byx8^SbQ0yk_hYo6-kFY*A%|DCzQ@;#5m!#nw7$un zx%#*|k)JYvJ)5OCXHZ&UKo}4P5(apE@Su#o#n_-;I?(7N0I+~=Ex6{h1jl$5eT%U{ zSRl%T0!^s0M+{}c(eGJ5-(qaggp;y|4`nkedqPn=zr_Y&EpH8 UZ!tEA9*F!1Xd0vu27Z-+57|7p<^TWy diff --git a/docs/deps/.DS_Store b/docs/deps/.DS_Store deleted file mode 100644 index 01ac6d59b0a4c64dd01d2fd4ef1004747d7a29c1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8196 zcmeI1!D|yi6vp3ZA;A_Zrb3Sk3Zf9nM$<#RtTA3h57MjBCQUV!#Eof+^tOWF$(wlg z=2h_MO%M7H=&2wG_Tojnis1KVCdrJ+n%N#y>P*;qVfTHz@AuyBY-U14qPpD-i57_{ zkB#loS#%Q`ALnhX9nyPF!V2h#wx~}%s#BMWW8Qv;&w$T>&w$T>&w$UszmNgEv$^F{ z-uvpP?|lY*2L8(o@c0m5V;gCkC@Y5!baDy+JA>V_;XCF5QWIz!X`3i3r8uXWJqRro zdWs>G9LEE8hmEvNlvQ#PN=`ywS?C#xkXMH;knSWRWqt26;4?6u0iL_hQ-flB`quot zLTBk5wy=FWTv?AhT`8`d-kq-K#I;(Z9XH^aFW-3jVDI(Yi!Q3>K2+V75#6$U`U?|z z`XF4#xQe5I@YlQ(*)lg zRI^Cs0qrk!q!aHXuanZ`UA<}WI;uy!+0{002|?2_x&_X=xL=E)y-yn;jj01$q$Tk3 zom;l<+J(v^SDnfFWv?=*tui0#hB;?17I7i|Wo*_pn7sh40f9 zCfkwaVI8Mj$E0#sSv&|E?KoWlPoJuCjc^kc+@e*wCTkgMw)3c6NF|%?#hYwulk?Q$ zVGT1}-(=q38EpQq%s&hMSdOu(juTn0e@OQ7dNMJ5S&lyoVc?E(H&uCvYPO zetC(tr4?L>Xaad(o1fX6q1N?pPP{u^D77U*bEMWuyMlc7#G0zg5;}sLdS`Z$HlT@IjIvp{b zq{HqtE>WxnC7qlOA5JSfolsn;j_dmnPA(C&)fg}ax(sZ{>6rWf(bw~TH_6V70b}4# zG2o(fp3ZPf+FN@!$Gz4=7f=?Cs|A}B9E4VkSZ>Ap&>*mTJ^&_)wID1I`w<8<*kTO) GCpLu(Qi*LrA}rMsz~U9?|(R7RYdoyKFWb zH`vzj7afqb>v7Eo+a(g$h1D+Qi9=B$;Hz#P^|m`gndn-ONjW#9PdVWVSW;Dn2izdVj5?S4>8hBAulw!Hx<5sP3P zuvGM~4p#mMK