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

react-quizzical

v1.1.0

Published

React component for asking a user a tree of questions

Downloads

12

Readme

react-quizzical

Travis npm package Coveralls

A react component for asking a tree of questions. Play with an interactive demo and read an intro.

Overview

A user answers a question, Do you love React?, by clicking No. A new question
appears, Do you love JavaScript? User goes back and clicks Yes on the first
question, and a different second question appears, What do you love about it?
This new question has a text field below.

To accomplish the above, here's the code you could write:

import { QuestionSet } from 'react-quizzical'

<QuestionSet
  questions={{
    ask: "Do you love React?",
    choices: [
      {
        text: "Yes",
        then: {
          ask: "What do you love about it?",
        }
      },
      {
        text: "No",
        then: {
          ask: "Do you love JavaScript?",
          choices: [
            { text: "Yes" },
            { text: "No" }
          ]
        }
      }
    ]
  }}
/>

As you can see, how the user answers one question determines which question will be shown next. Hence calling it a tree of questions.

Getting Started

Add react-quizzical to your project dependencies with npm

npm install -S react-quizzical

or yarn

yarn add react-quizzical

Then in the file where you want to use it, import a sub-component called QuestionSet using CommonJS syntax

var QuestionSet = require('react-quizzical').QuestionSet;

Or ES6 module syntax:

import { QuestionSet } from 'react-quizzical';

Note that QuestionSet is the only thing exported from react-quizzical at this time.

Now you are ready to use it.

Basic Props

QuestionSet requires at least two props, three to be useful.

  • questions: required: A tree of questions, which contains instructions for setting some variables. Example:

    questions={{
      ask: "When's the last time you moved?",
      type: "DATE",
      set: "moveDate"
    }}
  • template: required: A template to be filled-in with the variables specified by questions. Example:

    template={{
      title: "Moved",
      date: "{{moveDate}}"
    }}
  • onSave: a function to call with the filled-in template once the user answers to the end of a tree branch. If the user fills in "2018-01-06" with the examples above, it will result in onSave being called with:

    onSave({
      title: "Moved",
      date: "2018-01-06"
    })

More about the questions object

Each specific question in the flow can either be a free-form field or a multiple choice field.

Free-form field

Basic example:

{
  "ask": "When now brown cow?",
  "type": "DATE",
  "set": "when",
  "then": { ... }
}

More about each attribute:

  • "ask" - required - the question to ask
  • "set" - required - every free-form field must set a single variable. When the user types in their answer to the question, their answer will be stored in this variable. It can then be used in follow-up question's "ask" field or in the template. Read more about the templating system below.
  • "type" - Either leave this blank for a text field, or set it to "DATE" for a date field
  • "then" - The next field to show. Can be omitted to end the questioning after the user answers this one. Can be another free-form field. Or it can be a multiple choice field.

Multiple-choice field

Basic example:

{
  "ask": "In your best life you are a:",
  "choices": [
    {
      "text": "Stunt double",
      "set": { "occupation": "Stunt double", "emoji": ":dash:" },
      "then": { ... }
    },
    {
      "text": "Bird",
      "set": { "occupation": "Bird", "emoji": ":bird:" },
      "then": { ... }
    }
  ]
}

At the top level, both "ask" and "choices" are required.

For each individual choice, here's more about each attribute:

  • "text" - required - the wording of the choice.
  • "set" - Optional here! Note that it is a whole set of attributes, whereas a free-form field has only one attribute.
  • "then" - The next field to show. Can be omitted to end the questioning after the user answers this one. Can be a free-form field. Can be another multiple choice!

More about templating & variables

In the Question Set (see above), you can set a variable like this:

{
  "ask": "What's your favorite color?",
  "set": "color"
}

This will display a text box, and when the user fills it in, their answer will be set to the variable color, which can then be used later in the questions or in the template like this:

{
  "ask": "What do you think liking {{color}} says about you to other people?",
}

You can also set a variable with a Multiple Choice field like this:

{
  "ask": "Are you awesome?",
  "choices": [
    {
      "text": "Yes",
      "set": { "awesome": true }
    },
    {
      "text": "No",
      "set": { "awesome": false }
    }
  ]
}

You can use these variables in the same way. However, for this particular example, showing the text "true" or "false" is probably not what you want to do. Instead, you probably want to change the whole wording of follow-up questions (or, likewise, change the whole wording of the filled-in template sent to the onSave function).

How to do that?

Template Sections

You can include whole phrases based on the value of a variable like this:

{{#awesome}}That's sick, yo. {{/awesome}}Are you happy?

Sticking with the example above, if the user says "Yes" to the question "Are you awesome?", the next question could start with "That's sick, yo." Otherwise, if they answer "No," it will just ask the next question without the interjection.

You can also use this to insert variables, depending on if they're defined or not.

{{#name}}Hi, {{.}}! {{/name}}How are you today?

Here, if the variable "name" has been set to, for example, "Chad", the phrase will read "Hi, Chad! How are you today?" If the variable "name" has not been set, it will just read "How are you today?"

Template Inverse Sections

If you want a section to only appear if a variable isn't set, or is set to false, you can use an inverted section.

{{^name}}Weird that you don't have a name. Well. {{/name}}How are you today?

This can pair well with regular sections:

{{#awesome}}A bit conceited, are we?{{/awesome}}{{^awesome}}Aww, I'm sure you're cool!{{/awesome}}

Customizing the look & feel

In addition to the basic props listed above listed above, you can pass in any of the following:

prop | type | default | description -----|------|---------|------------ showSkipOnFirst | boolean | false | You can optionally pass in a skipLinkComponent and set this to true, which will then display your skipLinkComponent at the end of the first question skipLinkComponent | React Component | | See above saveButton | React Component | See defaults | The button to show at the end of the question flow dateInputComponent | React Component | See defaults | When a free-form field with "type": "DATE" is encountered, this is the date component that will be displayed. textInputComponent | React Component | See defaults | When a free-form field with no "type" attribute is encountered, this is the text component that will be displayed. freeFormFieldComponent | React Component | See defaults | When a free-form field is encountered, this component will be displayed. It will be passed a name, label, and children prop. multipleChoiceFieldComponent | React Component | See defaults | When a multiple choice field is encountered, this component will be displayed. It will be passed a label, and children prop. choiceComponent | React Component | See defaults | This is the component used to display each choice within a multiple choice field. Basically a radio input. It will be passed questionNumber, choiceNumber, onChange, checked, and text props.