GithubHelp home page GithubHelp logo

oliyh / re-learn Goto Github PK

View Code? Open in Web Editor NEW
140.0 5.0 9.0 1000 KB

A library for integrating tutorials into your re-frame/reagent application

Clojure 78.71% HTML 2.53% CSS 18.76%
lesson tutorial react clojurescript reagent spa

re-learn's Introduction

re-learn

Learn them good

Data-driven tutorials for reagent components with no changes required to your dom.

Live demo at https://oliyh.github.io/re-learn/.

Why?

Well-designed UIs are intuitive but even the best may need to introduce new features or train new users. Descriptions should be close to the element they are describing, both on screen and in your code.

Existing tutorial solutions rely on hooks into and mutation of your dom which does not work with React. Defining lessons separately from your code makes them subject to rot as behaviour changes and documentation is not updated.

re-learn allows you to describe lessons for your UI elements with data and generates walk-throughs for your users. It does not mutate your dom, making it React-friendly, and by writing the lesson right next to the code it describes you stand a better chance of keeping it up-to-date.

Versioning allows you to update descriptions when behaviour changes or is enhanced, ensuring that all your users are kept up-to-date with all the awesome features you're adding to your application.

Usage

Add re-learn to your project's dependencies: Clojars Project

Annotate reagent components with lessons describing the component and how to use it:

(require [re-learn.core :as re-learn]
         [re-learn.views :as re-learn-views])

(def purchase-button
  (re-learn/with-lesson
    {:id          :purchase-button-lesson
     :description "When you're ready, click here to purchase"
     :position    :bottom                  ;; optional, defaults to :right. values are :left, :right, :bottom, :top, :unattached, :bottom-left etc
     :version     2                        ;; optional, defaults to 1
     :attach      [:button#some-id]        ;; optional, position lesson relative to a dommy selector, see https://github.com/plumatic/dommy for use
     :continue    {:event :click           ;; optional, continue when this event occurs
                   :selector [:table :.tr]
                   :event-filter (fn [e] ...)}}

    (fn [] [:button.mdl-button.mdl-button--raised "Purchase"])))

Combine lessons into tutorials and attach them to views:

(def checkout
  (re-learn/with-tutorial
    {:id           :checkout-tutorial
     :name         "The checkout"
     :description  "Review your basket, check the price and confirm your purchase"
     :precedence   1 ;; optional, allows some tutorials to take precedence over others
     :auto-accept? false ;; optional, defaults to false
                         ;; when true will start the tutorial immediately when this component is rendered
                         ;; when false will display a snackbar indicating that a tutorial is available
     :lessons [{:id          :welcome-lesson ;; this is an inline lesson, not attached to anything
                :description "Welcome to the re-learn example"}
               basket
               totals
               purchase-button]}

    (fn [app-state]
      [:div
       [basket app-state]
       [purchase-button]])))

Let re-learn take care of everything else!

(defn- init []
  (let [app-root (js/document.getElementById "app")
        tutorial-root (js/document.getElementById "tutorial")
        app-state (fn [] ...)
    (reagent.dom/render [checkout app-state] app-root)
    (reagent.dom/render [re-learn-views/tutorial-view {:context? true}] tutorial-root)))

Look at the working examples for more details.

Style

re-learn has simple and structured markup making it easy for you to apply your own styles. To get started it's easiest to copy the reference version into your own project and adapt it as you wish.

Development

user> (dev)
dev> (start)
;; visit http://localhost:3449
dev> (cljs)
cljs.user>

CircleCI

License

Copyright © 2016 oliyh

Distributed under the Eclipse Public License either version 1.0 or (at your option) any later version.

re-learn's People

Contributors

andreacrotti avatar oliyh avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

re-learn's Issues

Key bindings

Right / enter to move forward
Left to go back
Escape to exit

Focus may be an issue, as might lessons with a "continue" action, although it should be possible to dispatch these synthetically.

Composable tutorials

Sometimes you have multiple self-contained tutorials on one screen (e.g navigation tutorial as well as home page tutorial). You should be able to compose them so they display in the right order.

->MapEntry from cljs core is overwritten by schema.core

I have a project with the following dependencies:

[[org.clojure/clojure "1.9.0"]
 [org.clojure/clojurescript "1.10.238"]
 [reagent "0.7.0"]
 [re-frame "0.10.5"]
 [re-learn "0.1.1"]]

When running my figwheel REPL, I get the following warning;

WARNING: ->MapEntry already refers to: cljs.core/->MapEntry being replaced by: schema.core/->MapEntry at line 751 public/js/out/schema/core.cljs

In the browser console, messages are telling me that my app has crashed.

core.cljs?rel=1524933586354:751 Uncaught TypeError: Cannot read property 'prototype' of undefined
    at core.cljs?rel=1524933586354:751
(anonymous) @ core.cljs?rel=1524933586354:751
core.cljs:1906 Uncaught Error: nth not supported on this type function (key_schema,val_schema,__meta,__extmap,__hash){
this.key_schema = key_schema;
this.val_schema = val_schema;
this.__meta = __meta;
this.__extmap = __extmap;
this.__hash = __hash;
this.cljs$lang$protocol_mask$partition0$ = 2229667594;
this.cljs$lang$protocol_mask$partition1$ = 139264;
}
    at Function.cljs.core.nth.cljs$core$IFn$_invoke$arity$3 (core.cljs:1906)
....
(a _bunch_ of more lines omitted)

I tried reproducing the problem in a lein new reagent-frontend mapentry-issue project, but couldn't. That project only had the following deps:

[[org.clojure/clojure "1.9.0"]
 [org.clojure/clojurescript "1.10.238"]
 [reagent "0.8.0"]
 [re-frame "0.10.5"]
 [re-learn "0.1.1"]]

lein deps :tree shows no conflicts.
I'm pulling in other stuff for my dev build, too, and I guess somewhere either in my code or my devtime deps that mapentry-thingie is producing the wrong result.

I'd like to use re-learn, so I'll spend some more time trying to figure out exactly where the issue lies. But it does seem like the schema.core dependency in re-learn is not healthy in conjunction with my particular version of clojurescript.

Re-learn usage across different pages

I used re-learn in my application on a single page and its working fine.
But can I use it across different pages ,like for example on a particular page change different tutorials should show up on start and on other page different tutorial should be triggered depending on the click of the first page in which there are two buttons.
like the tutorial should continue between different pages? Is this possible use-case with relearn?

Lessons should not clip off the screen

It should be possible to know the bounds of the screen and shift lessons such that they do not clip off the screen but appear wholly within the scrollable area.

If a lesson is entirely off the screen, it should be scrolled to with a nice transition.

Live demo

Essential to let people try before buy

Lesson popup remains open when I switch pages

I want to close popup and show other lesson popup after switching to new page
I solved problem of showing popup on other page using atom of clojure but I want to close popup without clicking on button provided by lesson

Allow developer to implement persistence other than local storage

The developer may wish to store learned lessons against a user profile, rather than per device. This means a function to load the lessons and a function to persist the lessons should be exposed to the user.

Not sure if it's possible to override re-frame fx handlers without warnings, but this would be the obvious route.

Help mode

In help mode, the user will see components that have a lesson highlighted in some way.
Clicking on the highlighted item will result in the lesson for that item being displayed.

As we know the position of each element they can be highlighted in the tutorial layer and do not need to be altered themselves.

Option for snackbar notification of lessons

Not everyone wants the UI blocked with lessons. An alternative would be to display a snackbar notifying the user that lessons are available if they wish to view them, or otherwise dismiss them.

Should just be a new view method, or maybe an option on the existing one.

Getting some errors in reframe and reagent

I used the project in my application. It shows errors on my terminal
-> Use of undeclared Var reagent.ratom/add-on-dispose! at line 32 resources/public/js/compiled/out/re_frame/interop.cljs

My code used is:

(def re-learn-component
(re-learn/with-lesson
{:id :basic-lesson
:description "Just testing how to use re-learn"
:position :bottom}
(fn []
[:div
[:div.h3
[:h3 "Ich bin Dhiren Serai"]]])))

(def check-re-learn
(re-learn/with-tutorial
{:id :test-tutorial
:name "check list"
:description "create your learning components"
:lessons [{:id :willkommen
:description [:div
[:h2 "Welcome"]]}
re-learn-component]}
(fn []
[:div
[:h5 "Hallo"]
[re-learn-component]])))

(defn mount-root
;;;Start of the application
[]
(re-learn/init)
(r/render [check-re-learn] (by-id "test")))

(.addEventListener js/document "deviceready"
mount-root
false)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.