{"id":13733496,"url":"https://github.com/carlganz/rintrojs","last_synced_at":"2025-04-09T21:13:01.816Z","repository":{"id":47153260,"uuid":"62968025","full_name":"carlganz/rintrojs","owner":"carlganz","description":"Wrapper for the Intro.js library","archived":false,"fork":false,"pushed_at":"2024-01-11T18:50:42.000Z","size":344,"stargazers_count":133,"open_issues_count":20,"forks_count":11,"subscribers_count":10,"default_branch":"master","last_synced_at":"2025-04-09T21:12:54.857Z","etag":null,"topics":["cran","introjs","r","shiny"],"latest_commit_sha":null,"homepage":"http://rintrojs.carlganz.com/","language":"R","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/carlganz.png","metadata":{"files":{"readme":"README.Rmd","changelog":null,"contributing":null,"funding":null,"license":"License","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2016-07-09T20:33:38.000Z","updated_at":"2025-03-22T11:12:14.000Z","dependencies_parsed_at":"2023-12-10T23:25:56.690Z","dependency_job_id":"8c26b367-5929-4c18-b268-1f09b4cd8c1c","html_url":"https://github.com/carlganz/rintrojs","commit_stats":{"total_commits":155,"total_committers":7,"mean_commits":"22.142857142857142","dds":"0.16774193548387095","last_synced_commit":"ea37b7ff2f66ca5a710ab4f903b74873b0af850f"},"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/carlganz%2Frintrojs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/carlganz%2Frintrojs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/carlganz%2Frintrojs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/carlganz%2Frintrojs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/carlganz","download_url":"https://codeload.github.com/carlganz/rintrojs/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248111973,"owners_count":21049578,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cran","introjs","r","shiny"],"created_at":"2024-08-03T03:00:44.210Z","updated_at":"2025-04-09T21:13:01.789Z","avatar_url":"https://github.com/carlganz.png","language":"R","funding_links":[],"categories":["R","Tools","UI Components"],"sub_categories":["Integrations","Walkthrough / Tooltip / Help"],"readme":"---\noutput: github_document\n---\n\n\n[![JOSS Status](https://joss.theoj.org/papers/10.21105/joss.00063/status.svg)](https://dx.doi.org/10.21105/joss.00063)[![Project Status: Active.](https://www.repostatus.org/badges/latest/active.svg)](https://www.repostatus.org/#active) [![R-CMD-check](https://github.com/carlganz/rintrojs/workflows/R-CMD-check/badge.svg)](https://github.com/carlganz/rintrojs/actions)[![CRAN_Status_Badge](http://www.r-pkg.org/badges/version/rintrojs)](https://cran.r-project.org/package=rintrojs)[![Licence](https://img.shields.io/badge/licence-AGPL--3-blue.svg)](https://www.gnu.org/licenses/agpl-3.0.en.html)[![minimal R version](https://img.shields.io/badge/R%3E%3D-3.0.0-6666ff.svg)](https://cran.r-project.org/)\n\nrintrojs\n========\n\n[R](https://www.r-project.org/) was originally developed with the name S in the 70's as a glue language. Statisticians at Bell Labs needed an interactive environment for working with their C and Fortran scripts. Decades later, R is still a glue language, except instead of C and Fortran, it brings together C++, and JavaScript. With the advent of the [Shiny](https://shiny.posit.co/) package, R is now a popular platform for developing data-driven web applications. As Shiny increases in popularity so will the complexity of the Shiny apps built. In many instances, new-users will require guidance when they first use a Shiny application.\n\nLuckily, there is already a well established JavaScript library for this purpose. [Intro.js](https://introjs.com/), written by Afshin Mehrabani, is a JavaScript library that helps integrate step-by-step introductions, and clickable hints into websites. The `rintrojs` R package integrates Intro.js into Shiny, so that users can easily add instructions to their application without having to use HTML, CSS, or JavaScript.\n\nInstall\n-------\n\n`rintrojs` is available on CRAN:\n\n```r\ninstall.packages(\"rintrojs\")\n```\n\nTo access the bleeding-edge version, use `devtools` to install `rintrojs` from github:\n\n```r\ndevtools::install_github(\"carlganz/rintrojs\")\n```\n\nUsage\n-----\n\nTo use `rintrojs`, you need to call `introjsUI()` once in the UI. `rintrojs` supports both static and programmatic introductions meaning you can either wrap the elements you want to introduce with `introBox`, or dynamically generate your introduction using the `steps` option (see [the Intro.js documentaion](https://github.com/usablica/intro.js/wiki/Documentation)). You specify the order of the introduction with the data.step parameter, and you specify the content of the introduction with the data.intro parameter. You can initiate the introduction from the server by calling `introjs(session)`. You can also specify options, and pass text as the body of javascript events associated with `Intro.js`.\n\nHere is an example with a static introduction, but with options, and events used. \n\n``` r\nlibrary(rintrojs)\nlibrary(shiny)\n\n# Define UI for application that draws a histogram\nui \u003c- shinyUI(fluidPage(\n  introjsUI(),\n  \n  # Application title\n  introBox(\n    titlePanel(\"Old Faithful Geyser Data\"),\n    data.step = 1,\n    data.intro = \"This is the title panel\"\n  ),\n  \n  # Sidebar with a slider input for number of bins\n  sidebarLayout(sidebarPanel(\n    introBox(\n      introBox(\n        sliderInput(\n          \"bins\",\n          \"Number of bins:\",\n          min = 1,\n          max = 50,\n          value = 30\n        ),\n        data.step = 3,\n        data.intro = \"This is a slider\",\n        data.hint = \"You can slide me\"\n      ),\n      introBox(\n        actionButton(\"help\", \"Press for instructions\"),\n        data.step = 4,\n        data.intro = \"This is a button\",\n        data.hint = \"You can press me\"\n      ),\n      data.step = 2,\n      data.intro = \"This is the sidebar. Look how intro elements can nest\"\n    )\n  ),\n  \n  # Show a plot of the generated distribution\n  mainPanel(\n    introBox(\n      plotOutput(\"distPlot\"),\n      data.step = 5,\n      data.intro = \"This is the main plot\"\n    )\n  ))\n))\n\n# Define server logic required to draw a histogram\nserver \u003c- shinyServer(function(input, output, session) {\n  # initiate hints on startup with custom button and event\n  hintjs(session, options = list(\"hintButtonLabel\"=\"Hope this hint was helpful\"),\n         events = list(\"onhintclose\"=I('alert(\"Wasn\\'t that hint helpful\")')))\n  \n  output$distPlot \u003c- renderPlot({\n    # generate bins based on input$bins from ui.R\n    x    \u003c- faithful[, 2]\n    bins \u003c- seq(min(x), max(x), length.out = input$bins + 1)\n    \n    # draw the histogram with the specified number of bins\n    hist(x,\n         breaks = bins,\n         col = 'darkgray',\n         border = 'white')\n  })\n  \n  # start introjs when button is pressed with custom options and events\n  observeEvent(input$help,\n               introjs(session, options = list(\"nextLabel\"=\"Onwards and Upwards\",\n                                               \"prevLabel\"=\"Did you forget something?\",\n                                               \"skipLabel\"=\"Don't be a quitter\"),\n                                events = list(\"oncomplete\"=I('alert(\"Glad that is over\")')))\n  )\n})\n\n# Run the application\nshinyApp(ui = ui, server = server)\n```\n\nYou can also generate introductions dynamically.\n\n``` r\nlibrary(shiny)\nlibrary(rintrojs)\n\nui \u003c- shinyUI(fluidPage(\n      introjsUI(),\n      mainPanel(\n        textInput(\"intro\",\"Enter an introduction\"),\n         actionButton(\"btn\",\"Press me\")\n      )\n   )\n)\n\nserver \u003c- shinyServer(function(input, output, session) {\n   \n  steps \u003c- reactive(data.frame(element = c(NA,\"#btn\"),\n                               intro = c(input$intro,\"This is a button\")))\n  \n  observeEvent(input$btn,{\n    introjs(session,options = list(steps=steps()))\n    \n  })\n  \n})\n\n# Run the application \nshinyApp(ui = ui, server = server)\n```\n\nClick [here to view example.](https://carlganz.shinyapps.io/rintrojsexample/)\n\nContributing\n------------\n\nPlease note that this project is released with a [Contributor Code of Conduct](https://github.com/carlganz/rintrojs/blob/master/CONDUCT.md). By participating in this project you agree to abide by its terms.\n\nIf you find any problems or have any questions, please feel free to file an issue. \n\n## Contributors ✨\n\nThanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):\n\n\u003c!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section --\u003e\n\u003c!-- prettier-ignore-start --\u003e\n\u003c!-- markdownlint-disable --\u003e\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://www.carlganz.com\"\u003e\u003cb\u003eCarl Ganz\u003c/b\u003e\u003c/a\u003e\u003cbr /\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/afshinm\"\u003e\u003cb\u003eAfshin Mehrabani\u003c/b\u003e\u003c/a\u003e\u003cbr /\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/etiennebacher\"\u003e\u003cb\u003eEtienne Bacher\u003c/b\u003e\u003c/a\u003e\u003cbr /\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/mvanbommel\"\u003e\u003cb\u003eMatthew van Bommel\u003c/b\u003e\u003c/a\u003e\u003cbr /\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/crew102\"\u003e\u003cb\u003e Chris Baker\u003c/b\u003e\u003c/a\u003e\u003cbr /\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n\u003c!-- markdownlint-restore --\u003e\n\u003c!-- prettier-ignore-end --\u003e\n\n\u003c!-- ALL-CONTRIBUTORS-LIST:END --\u003e\n\nThis project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcarlganz%2Frintrojs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcarlganz%2Frintrojs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcarlganz%2Frintrojs/lists"}