The QR Card component is a reusable, fully self-contained Web Component for dynamically generating and displaying QR codes along with related information within your web applications.
This is a solution to the QR code component challenge on Frontend Mentor.
- Overview
- Links
- Usage
- Screenshots
- Built with
- What I learned
- Continued Development
- Useful Resources
- Author
The qr-card
custom element encapsulates a visual card containing a QR code. The QR code is dynamically generated using the node-qrcode
npm package, which has been bundled with the component using Browserify. This means the component is fully self-contained and will work 'out of the box' with only a single <script>
tag in your HTML.
The QR code is generated based on the URL attribute provided to the component, and descriptive text is provided via the use of named slots.
- Solution URL: Web Component Source
- Live Site URL: Solution Landing Page
Download QRCard.js
from the components
folder and include it in a <script>
tag anywhere in your HTML. Set the defer
attribute so the script does not execute until after the page is finished loading. The component is fully self-contained, so no other external JavaScript is required.
Now you can include the <qr-code>
element anywhere in your HTML:
<qr-card url="https://www.frontendmentor.io/">
<h2 slot="heading">Improve your front-end skills by building projects</h2>
<p slot="caption">Scan the QR code to visit Frontend Mentor and take your coding skills to the next level</p>
</qr-card>
URL to encode as a QR code. There are currently no checks to enforce any specific URL pattern(s), so technically this can be any string up to 2048 characters.
The main heading. This should be an <h2>
element as this is what the component is expecting and styled for. No character limit is enforced.
The subheading or description. This should be a <p>
element as this is what the component is expecting and styled for. No character limit is enforced.
Add as many <qr-code>
elements to the page as your tender heart desires:
Using lifecycle callbacks we can watch the url
attribute for changes, and have the same component generate a new QR code any time it's updated:
- Web Components - Web Component API
- node-qrcode - QR code generator
- Browserify - Dependency bundler
- Flexbox - Fluid layout
- Semantic HTML
- Dev Tools - Debugging
- ChatGPT - Debugging
- Web Components API
- Web Component lifecycle callbacks
- Building a customization API via Web Component attributes
- Working with the shadow DOM
- Fluid layouts with Flexbox
- Writing better README files
The JavaScript driven, interactive component was fun to make!
<form class="qr-update">
<div class="url">
<label for="url">URL</label>
<input
type="text"
name="url"
id="url"
maxlength="100"
size="50"
placeholder="Enter a URL to encode"
/>
</div>
<div class="heading">
<label for="heading">Heading</label>
<textarea
name="heading"
id="heading"
maxlength="100"
placeholder="Enter your main heading here"
rows="4"
cols="50"
></textarea>
</div>
<div class="description">
<label for="description">Description</label>
<textarea
name="description"
id="description"
maxlength="250"
placeholder="A descriptive caption or subheading goes here"
rows="4"
cols="50"
></textarea>
</div>
<button id="submit">Submit</button>
</form>
<qr-card url="Update the QR Card with the form on this page!">
<h2 slot="heading">QR Cards can be updated dynamically</h2>
<p slot="caption">Use the form to pass in a URL, heading, and description text, and the component dynamically generates a new QR code</p>
</qr-card>
const urlInput = document.getElementById('url');
const headInput = document.getElementById('heading');
const descInput = document.getElementById('description');
function resetForm() {
urlInput.value = '';
headInput.value = '';
descInput.value = '';
}
function updateCard() {
const qrCard = document.querySelector('qr-card');
const qrHead = qrCard.querySelector('h2');
const qrDesc = qrCard.querySelector('p');
qrCard.setAttribute('url', urlInput.value);
qrHead.innerText = headInput.value;
qrDesc.innerText = descInput.value;
}
function submit(e) {
e.preventDefault();
updateCard();
resetForm();
}
document.querySelector('button').addEventListener('click', submit);
Some ideas for continued development:
- Enforce
url
attribute has valid url format(s) - Unit tests
- Functional tests
- Build on the customization API
- Scaling
- Choose vertical or horizontal layout
- Toggle drop shadow
- QR code background color
- QR code color
- Enforce slot element type
- As of right now it is up to the consumer of the compoent to slot the 'correct' HTML elements. The card expects an
<h2
and a<p>
, respectively. Using an<h1>
instead of<h2>
for example, will break the card.- One idea to fix this is to utilize the customization API and use attributes for the description text instead of slots
- As of right now it is up to the consumer of the compoent to slot the 'correct' HTML elements. The card expects an
-
Web Components - Web Components API reference
-
Lifecycle Callbacks - Lifecycle callbacks allow for dynamic and context-aware components
-
Context-Aware Web Components - More examples of lifecycle callbacks
-
Learn Web Components in 25 Minutes - Practical example of using Web Components API
-
Writing a Good README - The value of writing good README files cannot be overstated
- LinkedIn - Jason Sherrick
- Frontend Mentor - @j-sherrick
- GitHub - j-sherrick