# Registering Custom Component
# ▶️ Step 1.
Navigate to the 📁 HTML/js/components folder and create a new file named MyCustomComponent.js.
# ▶️ Step 2.
Open the created file and add the following code skeleton:
export default class MyCustomComponent extends BaseComponent {
constructor({
name,
loadInnerComponents,
parent,
element
}) {
super({
name,
loadInnerComponents,
parent,
element,
// Component default options
defaults: {
},
// Component inner elements
innerElements: {
}
});
}
}
# ▶️ Step 3.
Open the template's main frontend file 📄 HTML/js/app.js and register your component in the 🔧 app.components object as follows:
window.app = {
...
components: {
...
'MyCustomComponent': {
dependencies: [], // leave this empty for now
file: './components/MyCustomComponent.js' // path to your file
}
}
}
# ▶️ Step 4.
Open your component JS file 📄 HTML/js/components/MyCustomComponent.js and extend its code base with the following example:
export default class MyCustomComponent extends BaseComponent {
constructor({
name,
loadInnerComponents,
parent,
element
}) {
super({
name,
loadInnerComponents,
parent,
element,
// Component default options
defaults: {
myOption1: true,
myOption2: 'stringValue',
myAnotherOption: 55,
},
// Component inner elements
innerElements: {
myInnerElementsSet: '.js-my-custom-component__element',
myAnotherInnerElementsSet: '.js-my-custom-component__another-element',
}
});
// Setup the component and run the init() function
this.setup();
}
// Component code goes here
init() {
// You can organize it in functions
this.myFunction1();
this.myFunction2();
this.myFunction3();
}
// This is the place to clean up your component work if needed (optional)
destroy() {
console.log('This code will be automatically executed before the next page is loaded in an AJAX transition');
}
// Prepare your animation scene here (set initial values, positions, transforms, etc)
prepareAnimation() {
return new Promise((resolve) => {
const tl = gsap.timeline({
onComplete: () => resolve(true)
});
if (this.elements.myInnerElementsSet.length) {
tl.set(this.elements.myInnerElementsSet, {
y: '100%',
autoAlpha: 0
});
}
});
}
// Put the actual on-scroll animation scene there
getRevealAnimation() {
const tl = gsap.timeline({
paused: true
});
if (this.elements.myInnerElementsSet.length) {
tl.to(this.elements.myInnerElementsSet, {
y: '0%',
autoAlpha: 1,
stagger: 0.2
});
}
return tl;
}
myFunction1() {
console.log('1. Custom code here...');
}
myFunction2() {
console.log('2. Custom code there...');
}
myFunction3() {
console.log('3. Third function call');
// Use "this.options" to get a parsed object of the component options
console.log(`Here goes the value of "myOption1": ${this.options.myOption1}`);
console.log(`Here goes the value of "myOption2": ${this.options.myOption2}`);
console.log(`Here goes the value of "myAnotherOption": ${this.options.myAnotherOption}`);
// Use "this.element" for the reference of the component HTML element
console.log(`This is the component container HTML element`);
console.log(this.element);
console.log(`=================`);
// Use "this.elements" for the references of the inner component elements
console.log(`Component inner elements:`);
console.log(this.elements);
console.log(`=================`);
// Use "this.innerSelectors" to get the original selectors of inner elements
console.log(`Here are selectors of the inner elements:`);
console.log(this.innerSelectors);
console.log(`=================`);
}
}
# ▶️ Step 5.
Open any HTML page of the template and add the custom component code to the main page container.
<main
class="page-wrapper bg-gray-3"
id="page-wrapper"
data-barba="container"
data-arts-color-theme="dark"
>
<div
class="page-wrapper__content"
id="page-wrapper__content"
>
<div
class="d-flex js-my-custom-component"
data-arts-component-name="MyCustomComponent"
data-arts-component-options="{}"
data-arts-os-animation="true"
>
<div class="w-100 js-my-custom-component__element">Inner element 1</div>
<div class="w-100 js-my-custom-component__element">Inner element 2</div>
<div class="w-100 js-my-custom-component__element">Inner element 3</div>
</div>
</div>
</main>
You can have multiple instances of your component as well. Each instance can have its own options and inner elements. Note the custom options set on the 2nd instance in the example below. Those will override the component defaults using a "deep-merge" algorithm.
<main
class="page-wrapper bg-gray-3"
id="page-wrapper"
data-barba="container"
data-arts-color-theme="dark"
>
<div
class="page-wrapper__content"
id="page-wrapper__content"
>
<!-- Instance #1 -->
<div
class="d-flex js-my-custom-component"
data-arts-component-name="MyCustomComponent"
data-arts-component-options="{}"
data-arts-os-animation="true"
>
<div class="w-100 js-my-custom-component__element">Inner element 1</div>
<div class="w-100 js-my-custom-component__element">Inner element 2</div>
<div class="w-100 js-my-custom-component__element">Inner element 3</div>
</div>
<!-- Instance #2 (no animation, different options) -->
<div
class="d-flex js-my-custom-component"
data-arts-component-name="MyCustomComponent"
data-arts-component-options="{myOption1: false, myOption2: 'different string'}"
>
<div class="w-100 js-my-custom-component__element">Inner element of the 2nd instance 1</div>
</div>
</div>
</main>