Vivid, Vonage’s design system, is now published. What better way to celebrate Vivid’s public birthday than to build a birthday quiz? Let’s have a vivid birthday!
Vivid is an open-source vanilla JavaScript design system built upon the web components technology. It holds a growing repertoire of web components that a developer can use regardless of framework. Its theming system allows you to tweak it to your brand easily.
We’ve just launched vivid V3. That also means it’s kind-of vivid’s birthday.
Table of Contents
Birthday Present
One of our team members had a birthday lately, and we thought to combine the two parties. We purchased a fancy voucher and thought of a way to give it to her that’s not just a simple dry email.
Why make it easy on the birthday person? Let’s create a vivid-powered birthday quiz and let her work hard to get her birthday present!
If you are eager to see what we’re going to build, check it out:
See the Pen Birthday Quiz by Yonatan Kra (@yonatankra) on CodePen.
Find a Quiz You Like
The first step is to find questions. Google is a great helper. Our beloved team member is a CSS groupie, so I found this CSS jokes website.
Quiz Data Model
I chose a few of the jokes and put them into a data model (which is a fancy way to say: JSON):
The model above holds four questions and four correct answers. I’ve separated the questions from the answers because, in a fullstack implementation, I’d probably keep the answers away from the frontend side (we are sending this to a developer proficient in chrome dev tools…).
Now that we have our questions let’s move on.
Quiz Design
Designing something with Vivid is easy, even if you lack any UX skills (like me). I quickly found the components I needed to use from the docs (and yes, the fact that I developed some of them myself helped a bit 😉 ):
- Layout – to position elements easily on the page
- Dialog – to show feedback to the user
- Card – to show the question over a nice elevated surface
- Text-field – a way to add the answers
- Button – a nicely designed interaction components
Here’s how I composed them together:
In this design, the user sets the answers inside the text-fields and submits them to move on to the next step. Note that we can have multiple answers as in the image above (both right
and margin
).
If the answer is incorrect, a dialog appears:
Adding the Components
I begin with a simple HTML page and add the needed files for it.
Import the CSS files
In the head section, I imported the needed styles. In this case I’m using the CDN:
Import the JavaScript Files
In the body part I added a script tag of type module
and import the JavaScript files:
Quiz Layout
Above the script tag, I added the quiz’s layout:
Birthday Logic
Now that we have the components and layout, we need to implement the quiz itself.
Start the Quiz
For this I’ll create a start
function that will be activated by a click on the button:
function start() {
addNextQuestion(QUESTIONS[0]);
}
startButton.addEventListener('click', start);
We’ll create the function addNextQuestion
that accepts a question and shows it on screen:
This function generates the question’s HTML and replaces the card’s HTML with it. Now we need to implement the generateCardContent
function:
This function returns a string with (hopefully) valid HTML. It adds a div that will enter the main
slot of the card. Inside we add the CSS code of the question as preformatted text (the pre
tag).
Note the use of reduce
on the question’s properties which returns the valid structure for the view we want. Another reduce
after the pre
on the properties adds the text fields for the answers.
The final step is the submit button.
So for the question:
{
id: '1',
selector: '#wife',
properties: ['right', 'margin'],
}
We will get the following view:
Answer Validation
The submit button has a function attached to it via HTML binding onclick
. When it is clicked, a getAnswer
function is called with question.id
as a parameter. Let’s implement it now:
This function grabs the response from the text fields in the card via the prepareAnswerFromTextFields
function (see the implementation here).
It then finds the question’s index and verifies the answer vs. the model.
If the error property of the response is true, we call the error method with the error.
Otherwise, we call success and move to the next question.
Error and success control the dialog and look like this:
The Winning State
We have one final state – to show our happy colleague her present!
Let’s add a new type of question called reward
:
{
id: ‘5’,
rewardUrl: ‘https://www.canva.com/design/DAFbHyox0hc/_-bdsK86jcCqTu_21kjj9w/view’
}
In our addNextQuestion
function we can add the logic to handle it:
addNextQuestion
now handles a question with a rewardUrl
property and calls showWinningModal
to give the winner her prize:
Here’s the full code:
And a live demo of the quiz is live on codepen: Birthday Quiz.
The Layout
The vwc-layout
element is a powerful tool to help us arrange our elements on screen. By replacing the div
inside the card
with vwc-layout
with gutters
I get the following change:
And there’s no need to setup margins or anything.
Going Fullstack
Note that I’ve made verifyAnswer
an async function. This is because I could easily replace lines 3-5 with an async call to a server for response.
It’s just that easy 🙂
Summary
Building a UI with a web components library is very easy, and doesn’t require any framework (not even jQuery!).
Because the elements are native, you can use them with any framework (for instance, use v-repeat
for the vwc-text-field
instead of the reduce
function).
In addition, the layout
element is very powerful if you want to quickly arrange your elements nicely, as I did in the end result.
Wanna give it a go? Checkout Vivid’s components and build something nice to your loved one(s).
Thanks a lot to Rachel B. Tannenbaum and Yinon Oved for the kind and thorough feedback.
having such a library providing all the UI is a life saver! great serve yonatankra