-
Matthieu Fesselier authoredMatthieu Fesselier authored
Developping a comoponent with SiBTemplateElement
Warning
To start this tutorial, you should have followed this first part .
For the example, we are gonna make a FAQ component like this:
1. Create a component that extends SolidTemplateElement
Here is the minimum code your component must contain that extends SolidTemplateElement
.
// First import SolidTemplateElement import SolidTemplateElement from 'https://unpkg.com/@startinblox/core@0.10/dist/solid-template-element.js'; // Name your component and extend SolidTemplateElement export class SolidFAQ extends SolidTemplateElement { //This method help you to definie the attributes you want static get propsDefinition() { return { dataSrc: 'data-src', attributeCustom: 'xyz', } } // Finally, create the template of your component. template( { dataSrc, attributeCustom } ) { if (!dataSrc) return ''; let yourTemplate = ``; return yourTemplate } } customElements.define('solid-faq', SolidFAQ);
2. Define the attributes you want for your component
What custom settings do you want for your component? Let's assume we want to customize the title and the email of the moderator.
It's in your static get propsDefinition()
method that it takes place.
static get propsDefinition() {
return {
dataSrc: 'data-src',
title: 'title',
moderatorEmail: 'moderator-email'
}
}
Note
All the SiB components have the attribute data-src
, which receives the data sources for the component.
3. Create your template
Pass your attributes to your template and write it.
//Pass attribute to your template
template( { dataSrc, title, moderatorEmail } ) {
//Write your template
if (!dataSrc) return '';
let tmpl = `
<h3>${title}</h3>
<solid-display
data-src="${dataSrc}"
fields="question, answer"
class-question="accordion"
class-answer="panel"
id="test"
></solid-display>
`;
if(moderatorEmail) {
tmpl += `
<a href='mailto:p.${moderatorEmail}?subject=A%20new%20question%20for%20the%20FAQ&body=Hi!'>
Your question question not here ?
</a>
`;
}
return tmpl
}
As you can see, we've set classes to the question and answer fields to help us managing the accordion.
4. Implement JS and CSS in your component
Create a js file, like /js/main.js
.
Add the JS you need to make your accordion work, like this:
// /js/main.js
var component = document.getElementById("test");
component.addEventListener("populate", (event) => {
var acc = document.getElementsByClassName("accordion");
var i;
for (i = 0; i < acc.length; i++) {
acc[i].addEventListener("click", function () {
this.classList.toggle("active");
var panel = this.nextElementSibling;
if (panel.style.maxHeight) {
panel.style.maxHeight = null;
} else {
panel.style.maxHeight = panel.scrollHeight + "px";
}
});
}
})
Here is the CSS used for the demo:
/* /css/main.css */
.accordion {
background-color: black;
color : white;
cursor: pointer;
padding: 18px;
text-align: left;
border: none;
outline: none;
transition: 0.4s;
display : block;
}
.active, .accordion:hover {
background-color: blue;
}
.panel {
padding: 0 18px;
background-color: white;
max-height: 0;
overflow: hidden;
transition: max-height 0.2s ease-out;
display : block;
}
.accordion:after {
content: '\02795'; /* Unicode character for "plus" sign (+) */
font-size: 13px;
color: white;
float: right;
margin-left: 5px;
}
.active:after {
content: "\2796"; /* Unicode character for "minus" sign (-) */
color: white;
}
SiB framework provide you Helpers function to add JS and CSS in your component.
Add at the begin of your solid-faq.js
, import your JS and CSS with those functions:
//Import Helpers functions from the core
import { importCSS, importJS, uniqID } from 'https://unpkg.com/@startinblox/core@0.10/dist/libs/helpers.js';
//Use the Helpers functions
Helpers.importJS(`/js/main.js`);
Helpers.importCSS(`/css/main.css`);
export class SolidFAQ extends SolidTemplateElement {
....
4. Set fake datas
Creating data sources is quite another matter. For the example, we will use static data in JsonLD.
Create a file named datas-faq.jsonld
at the root of your project and put these datas:
{
"@id": "",
"@type": "ldp:Container",
"ldp:contains": [
{
"question": "How to plant cabbages?",
"answer": "Start seeds indoors 4 to 6 weeks before the last frost in spring. Sow seed outdoors when the soil can be worked in spring. Place transplants in the garden when they are 3 to 4 inches tall as early as 3 to 4 weeks before the last frost in spring. In cool-summer regions, plant cabbage in late spring for a fall harvest.",
"@id": "questions-1",
"permissions": []
},
{
"question": "How deep do you plant carrots?",
"answer": "Seeds should be planted about a ½ inch deep and 1 to 2 inches (2.5 to 5 cm.) apart. When growing carrots in the garden, you'll wait for your carrot plants to appear. When the plants are 4 inches (10 cm.)",
"@id": "questions-2",
"permissions": []
}
],
"permissions": [],
"@context": "https://cdn.happy-dev.fr/owl/hdcontext.jsonld"
}
5. Implement your component
Use the component in your index.html
.
If your component uses some core component like solid-display
, don't forget to import it in the <head>
of your file.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script type="module" src="https://unpkg.com/@startinblox/core@0.10"></script>
<script src="solid-faq.js" type="module"></script>
<title>Youpi !</title>
</head>
<body>
<solid-faq
data-src="./datas-faq.jsonLD"
fields="question, answer"
moderator-email="alice@startinblox.com"
title="Super faq"
></solid-faq>
</body>
</html>
6. Test your component:
npm run serve
7. Translate your component
To translate the static strings of your components, follow these steps:
- In your component, create a folder which contains all the translation files. You can name it
locales
for example. Inside, create one file per language, with the structure[code_language].json
, for example:fr.json
. - In each file, add one line per string to translate. Your file should look like this:
{
"title": "Solid FAQ",
"label.question": "Your question is not here ?"
}
- In the constructor of your component, define the path of your folder:
const base_url = "https://unpkg.com/@startinblox/solid-faq"; // url of your component
export class SolidFAQ extends SolidTemplateElement {
constructor() {
...
this.setTranslationsPath(`${base_url}/locales`);
}
...
}
- Use the
localize
method to show the translated strings in your template:
const base_url = "https://unpkg.com/@startinblox/solid-faq"; // url of your component
export class SolidFAQ extends SolidTemplateElement {
...
template( { dataSrc, title, moderatorEmail } ) {
if (!dataSrc) return '';
let tmpl = `
...
<a href='mailto:p.${moderatorEmail}?subject=A%20new%20question%20for%20the%20FAQ&body=Hi!'>
${this.localize('label.question')}
</a>
`;
return tmpl
}
}
As a developer who uses a component, you can also add you own translation files by targeting you translation folder. Like for the component, this folder should contain one file per language:
<sib-conversation
data-src="./data/conversations.jsonld"
extra-translations-path="http://my_app/locales"
></sib-conversation>
8. Does it work well?
If you get any trouble (or any idea to improve!), please mail me :)
Go Deeper
Discover other features of the framework playing with the demo on the website.