npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

instructorjs

v0.2.1

Published

On-screen tutorials for web pages and web applications

Downloads

30

Readme

InstructorJS

On-screen tutorials for web pages and web applications

Overview

InstructorJS provides a simple way to add tutorials to your website or web application.

Check out the demo here, and the demo source here.

Dependencies

InstructorJS depends on JQuery version 2.2.4, JQuery ScrollTo version 2.1.2, and Konva version 4.1.2.

Install

Pull it via Yarn/NPM, or grab the minified versions from this repository.

$ yarn add instructorjs

or

$ npm i instructorjs

Once installed, you'll import the javascript and css files into your page:

<html>
  <head>
    <!-- import the InstructorJS styles -->
    <link
      rel="stylesheet"
      href="/node_modules/instructorjs/instructor.min.css"
    />

    <!-- import the InstructorJS dependencies -->
    <script src="/node_modules/jquery/jquery.min.js"></script>
    <script src="/node_modules/konva/konva.min.js"></script>

    <!-- import the InstructorJS library -->
    <script type="module" src="/node_modules/instructorjs/instructor.min.js">
      import {jqueryScrollTo} from 'jqueryScrollTo/jquery-scrollto.min.js';
      import {InstructorFactory} from 'instructor/instructor.min.js'
      jqueryScrollTo(window.$);
    </script>
  </head>
  ...
</html>

Fonts

The default font for Instructor is Gemelli and should be placed at /fonts/gemelli.ttf.

You can override this in your sites CSS, to import from a different location or import another font altogether:

@font-face {
  font-family: "Pacifico";
  src: url("/path/to/fonts/Pacifico-Regular.ttf") format("truetype");
  font-weight: normal;
  font-style: normal;
}
.instructor .instructor_label {
  font-family: "Pacifico", "Arial";
}

Usage

Create an Instructor instance and pass a configuration object.:

    const instructorFactory = InstructorFactory();
    var instructor = new instructorFactory({
  onEnd: function(startNextTutorial, cb) {
    console.log("Tutorial Done!");
  }
});

Then, you call the run() method, passing the array of tutorial Steps:

instructor.run([
  {
    event: "next",
    description: "Hi, Welcome to the tutorial.  Click <em>Next</em> to begin!"
  },
  {
    event: "click",
    selector: "#btnSave",
    description: "Click the <strong>Save</strong> button to continue."
  },
  {
    event: "finish",
    description: "This completes the tutorial!"
  }
]);

For information on tutorials that span multiple pages of a website, see Multi-Page Tutorials

See below for information on step configuration:

Instructor Configurations

customValidators: (object) Collection of validation functions to use within steps. E.g. an email validator:

var instructor = new Instructor({
  customValidators: {
    emailValidator: function(value) {
      var emailRegex = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
      return emailRegex.test(String(value).toLowerCase());
    }
  }
});

onEnd: (function) Called when the tutorials are complete. Provides 2 arguments:

  • triggerNextTutorial: Passes the triggerNextTutorial from the main configs or final step config.

  • callback: If provided, should be executed after your onEnd logic is processed, to facilitate final cleanup.

onNext: (function) Invoked on each step of the tutorial.

onSkip: (function) Invoked when the user clicks the 'X' to skip the tutorial.

onStart: (function) Invoked when the tutorial begins.

nextLabel: (string) The label to show on the next button, default is Next

finishLabel: (string) The label to show on the finish button, default is Finish

sanitizer: (function) A function that takes string and returns the sanitized version of the string, used to do replacements within the step description text. Can be useful when needing to substitute values in the description, such as the host of a URL. For example:

var instructor = new Instructor({
  sanitizer: function(str) {
    str = str.replace(
      /\*\|current_url\|\*/g,
      window.location.origin + window.location.pathname
    );
    return str;
  }
});

These configurations can exist on the main config object or on the final step config

navigateOnFinish: (string) An optional URL to navigate the browser to, upon completion of the tutorial.

navigateOnFinishTarget: (string) The window target, i.e. _blank, _self, etc

reloadOnFinish: (boolean) Reload the browser, upon completion of the tutorial.

triggerNextTutorial: (boolean) Passed to the onEnd() function, to indicate the next tutorial should be started.

Step Configurations

event: (string) The type of event that triggers advancement from this step. Types are:

  • next: Provides a next button and advances on button click.

  • trigger: Advances on a DOM event. See triggerEvent below.

  • auto: Immediately advances (no user interaction required).

  • finish: Provides a finish button and completes the tutorial upon click.

  • select: Advances on selection of an HTML select control.

  • submit: Advances on HTML form submission.

  • key: Advances on keystroke. See keyCode below.

description: (string) The text to display for this step. Can include HTML. See Description Styling below.

selector: (string) The CSS selector or element reference that corresponds to the area that will be highlighted (cutout and arrow).

preventInteraction: (boolean) Whether or not the user should be able to interact with the highlighted area | default: false

defaultValue: (string) The initial value to set on the input control (or any element supporting .val()).

eventSelector: (string) Use this to specify an alternate selector or element reference, when the element that you want to highlight differs from the one that will produce the event.

triggerEvent: (string) When using the trigger event type, this used to specify the event that will cause the trigger, such as click.

validation: (object) Validates a input control before allowing advancement. Properties include:

  • selector: (string) The CSS selector or element reference of the element that is going to be validated.

  • customValidator: (string) Optionally, the name of validator from the customValidators top-level configurations.

  • valueFunction: (string) The JQuery function to call on the element to get the value for comparison, e.g. "val","html","text",etc.

  • value: (string) The value to compare to the result of the valueFunction to test validity.

  • invert: (boolean) Whether the inverse of the value test is valid. Useful for testing for not empty when value is set to ""

exists: (boolean) Only runs the step if the selector is actually present on the page.

marginX/marginY: (number) Extra margin within the highlight area, making the cutout larger

bottom/left/right/top: (number) Reduces the size of the highlight area, making the cutout smaller (negative numbers have the opposite effect)

timeout: (number) Time, in millis, to delay before the step displays (such as waiting for a page animation to complete). | default: 100

noScroll: (boolean) When highlighting an element, do not try to automatically scroll the element into view. | default: false

preventAutoFocus: (boolean) When highlighting an element, do not apply focus automatically to the element. | default: false

scroller: (string|element) CSS selector or element reference that will be used to scroll the highlighted element into focus. | default: document.body

repositionEvent: (object) Used to reposition the text/highlight/arrow on a page event (things on the page moved around while the step was shown). Properties include:

  • selector: (string|element) CSS selector or element reference to listen for the event on.

  • event: (string) The name of the event to listen for.

shape: (string) The shape of the highlight cutout. Options are "rect" and "circle". | default: rect

radius: (number) If using a "circle" shape, this controls the radius of the highlight cutout. | default: computed off the max dimension of the element

onBeforeStart: (function) Invoked before the step is run.

onAfterEnd: (function) Invoked after the step is run.

isBootstrapEvent (boolean) If using Bootstrap, this can be used to handle Bootstrap events, such as setting the event property to show.bs.modal, in order to advance the step when the Bootstrap modal is shown.

isTinyMce: (boolean) If using TinyMCE, set this to true, in order to set the defaultValue of the text editor. | default: false

scrollAnimationSpeed: (number) Controls the speed of the animation of the step content and scrolling (in millis). | default: 250

Description Styling

Within the step description HTML string, there are a few HTML tags that have been repurposed as short-hand for certain style characteristics. Classes are available, as an alternative.

They include:

<strong/>: Blue font color, generally used to draw attention to a specific word or phrase. | CSS class instructor_primary

<em/>: Green font color, generally used to indicate an action with positive outcome. | CSS class instructor_success

<del/>: Red font color, generally used to indicate an action with negative outcome. | CSS class instructor_danger

<ins/>: Yellow font color, generally used to indicate example text. | CSS class instructor_example

Multi-Page Tutorials

Often, you'll have tutorials that span multiple pages of a website, or need to continue after a browser refresh. InstructorJS does not maintain state, but does provide a few hooks that let you easily manage progress of a tutorial, so that you can resume a tutorial across navigation/reload. The Demo provided with InstructorJS illustrates this simply using LocalStorage, but you could store progress in whatever manner makes sense for your application.

The relevant parts of the demo explained:

//find the current tutorial Id stored in LocalStorage
var cachedTut = localStorage.getItem("instructor-tut");

//if it doesn't exist, then we're at zero (the beginning)
var finishedTut = cachedTut ? Number(cachedTut) : 0;

//Start InstructorJS
runTutorial();

function runTutorial() {
  //Create an InstructorJS instance
  var instructor = new Instructor({
    onSkip: function() {
      //if we click the "X" button to skip the tutorial, let's remove any progress so far
      localStorage.removeItem("instructor-tut");
    },
    onEnd: function(startNextTutorial, cb) {
      //done with the tutorial, increment the counter and update LocalStorage
      ++finishedTut;
      localStorage.setItem("instructor-tut", finishedTut);
      //call the callback, mainly necessary for "submit" event types
      if (cb) cb();
      //if the tutorial is configured to kick the next tutorial on completion, start it
      //otherwise, clear out LocalStorage, so the demo can be restarted on next visit
      if (startNextTutorial) runTutorial();
      else localStorage.removeItem("instructor-tut");
    }
  });
  getTutorial(finishedTut + 1).then(data => {
    //checking a "route" arg, to make sure the tutorial should be run for the current page/route
    if (location.pathname.endsWith(data.route)) instructor.run(data.steps);
  });
}

function getTutorial(tutId) {
  //grabs the tutorial data for the desired tutorial, which is stored in a
  //separate JSON file in the demo
  return fetch(`../tutorials/tutorial-${tutId}.json`).then(res => res.json());
}

Build

Install build dependencies:

$ yarn install

or

$ npm install

Create the minified JS/CSS:

$ yarn build

or

$ npm run build

or

$ gulp

Run the demo locally:

$ node server.js

Then, navigate to http://localhost:8080/demo/website/index.html

CREDITS

Draws initial inspiration and code from EnjoyHint

LICENSE

MIT