Exploring Component Inheritance in Aventus
Tags: webdev, javascript, webcomponents, inheritance
Published: 2023-06-25 10:22:32

##Introduction

In the world of web development, reusability and modularity are crucial aspects. One powerful technique that aids in achieving these goals is the concept of inheritance. In this article, we will delve into how Aventus, the innovative web framework, leverages object-oriented programming (OOP) principles to enable component inheritance. We will explore the implementation of a Shape component and demonstrate how it serves as the foundation for creating specialized components like Rectangles and Triangles. Join us on this journey as we unlock the potential of component inheritance in Aventus.

## Preamble - Understanding Aventus Component Files

Before we dive into exploring component inheritance in Aventus, let's take a moment to understand the different types of files used in Aventus and their respective purposes. Aventus adopts a modular approach to web component development, separating the logic, style, and view of each component into distinct files. These files are typically denoted with different extensions to signify their roles.

The following file extensions are commonly used in Aventus component development:

- **.wcl.avt** (Web Component Logic): This file extension is used for writing the logic of a web component in TypeScript. It contains the component class definition, properties, methods, and other related logic.

- **.wcs.avt** (Web Component Style): The .wcs.avt files hold the styling information for a web component. They are written in SCSS (Sassy CSS) and define the visual appearance, layout, and other presentational aspects of the component.

- **.wcv.avt** (Web Component View): The .wcv.avt files describe the structure of a web component using HTML. They define the markup and layout of the component, including the placement of elements and slots.

In addition to these separate files, Aventus also supports a consolidated file format for convenience:

- **.wc.avt** (Web Component): The .wc.avt file combines the logic, style, and view of a web component into a single file. It encapsulates all the necessary code and provides a compact representation of the component.

Understanding these file types and their purposes will help you navigate and work effectively with Aventus components. With this knowledge, let's proceed to the main sections of the article, where we explore the concept of component inheritance and its implementation in Aventus.

Feel free to refer back to this preamble section whenever you encounter these file extensions while working with Aventus components.

## Introducing the Shape Component

The Shape component acts as an abstract class that defines the fundamental behavior and properties shared by various shapes. Let's take a look at the code for the Shape component:

```typescript
// Shape.wcl.avt
/**
 * The shape class is an abstract class that define basic behavior for a shape
 */
export abstract class Shape extends Aventus.WebComponent implements Aventus.DefaultComponent {

    // Properties
    @Property((target: Shape) => {
        target.style.setProperty("--shape-width", target.width + 'px');
    })
    public width: number = 100;

    @Property((target: Shape) => {
        target.style.setProperty("--shape-height", target.height + 'px');
    })
    public height: number = 100;

    // View Element
    /** Selector for the div where the name will be displayed */
    @ViewElement()
    protected nameDisplay: HTMLDivElement;

    // Methods
    /** Force child to define a name */
    protected abstract defineName(): string;
    /** Force child to define the calculation method */
    public abstract getArea(): number;

    protected override postCreation(): void {
        this.nameDisplay.innerHTML = this.defineName();
    }
}
```
```scss
/* Shape.wcs.avt */
:host {
    height: var(--shape-height);
    margin: 40px;
    position: relative;
    width: var(--shape-width);
    background-color: red;

    .name {
        height: 25px;
        left: 0;
        position: absolute;
        top: -25px;
    }
}
```

```html
<!-- Shape.wcv.avt -->
<div class="name" @element="nameDisplay"></div>
<slot></slot>
```

The Shape component defines the basic behavior for a shape, including properties for width and height, as well as a name display element. Child components will inherit from this abstract class and provide their own implementation of the defineName() and getArea() methods.

## Extending Shape with Rectangles

In this example, we will create a Rectangle component that extends the Shape component we defined in previous section. Since the Rectangle component shares the same style and structure as its parent, there is no need to create separate Rect.wcs.avt and Rect.wcv.avt files. We will focus on implementing the required functions defined by the parent.

To create the Rectangle component, we only need to create the Rect.wcl.avt file in the Rect folder. Aventus's auto-completion feature will assist us in generating the missing functions automatically.

Here's the content of the Rect.wcl.avt file:

```typescript
import { Shape } from "../Shape/Shape.wcl.avt";

export class Rect extends Shape implements Aventus.DefaultComponent {
    
    /**
     * @inheritdoc
     */
    protected override defineName(): string {
        return "Rectangle";
    }
    
    /**
     * @inheritdoc
     */
    public override getArea(): number {
       return this.width * this.height;
    }
}
```

With just a few lines of code, we have created a Rectangle component that inherits the behavior and properties of the Shape component. The defineName() function returns the name of the shape as "Rectangle," and the getArea() function calculates the area of the rectangle based on its width and height.

## Triangle Component - Extending the Style and Structure

In this section, we will create a Triangle component that extends the Shape component using a single file to consolidate the logic, style, and structure. By doing so, we can efficiently define the unique characteristics of the Triangle component.

To create the Triangle component, we will create the Triangle.wc.avt file in the Triangle folder. This file will contain the script, template, and style sections. We will override the parent's style to remove the red background defined by the Shape component and add custom styles to draw the triangle shape. Additionally, we will modify the structure by adding a `<div>` element with the "triangle" class to represent our triangle shape. This `<div>` element will replace the `<slot>` tag in the Shape component.

Here's the content of the Triangle.wc.avt file:

```html
<script>
    import { Shape } from "../Shape/Shape.wcl.avt";

    export class Triangle extends Shape implements Aventus.DefaultComponent {
        /**
        * @inheritdoc
        */
        protected override defineName(): string {
            return "Triangle";
        }
        
        /**
        * @inheritdoc
        */
        public override getArea(): number {
            return (this.height * this.width) / 2;
        }
    }
</script>

<template>
    <!-- Replace the slot with the triangle shape -->
    <div class="triangle"></div>
</template>

<style>
    :host {
        /* Override parent's rule to remove the red background */
        background-color: transparent;

        .triangle {
            /* Define the triangle shape */
            border-bottom: var(--shape-height) solid red;
            border-left: calc(var(--shape-width) / 2) solid transparent;
            border-right: calc(var(--shape-width) / 2) solid transparent;
            height: 0;
            width: 0;
        }
    }
</style>
```
In this code snippet, we define the Triangle component by extending the Shape component. We override the defineName() function to return the name "Triangle" and the getArea() function to calculate the area based on the triangle's width and height. The structure of the Triangle component includes a `<div>` element with the "triangle" class, which represents the visual representation of the triangle shape.

## Final result

To visualize the result of our code, let's create a file with the following code. This will showcase the final outcome of our Shape, Rect, and Triangle components working together seamlessly.

Create a new HTML file, let's name it index.html, and include the following code:

```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="/shape.js"></script>
</head>
<body>
    <av-triangle height="75" width="50"></av-triangle>
    <av-rect height="75" width="50"></av-rect>
</body>
</html>
```

Once you have created this index.html file, you can open it in a web browser to see the final result. The Shape, Rect, and Triangle components will be rendered on the screen with the specified dimensions. This allows you to visually observe the outcome of our code and appreciate the flexibility provided by inheritance in Aventus.

![Final Result](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eg2xsnggw6nc50py4b8u.png)

## Conclusion

In conclusion, Aventus emerges as a promising challenger in the realm of web frameworks by introducing a powerful mechanism for web component inheritance. Leveraging object-oriented programming (OOP) principles, Aventus empowers developers to create complex and reusable components with ease. The ability to define an abstract base component and extend it with specialized child components brings tremendous flexibility and scalability to web development projects.

By embracing the concept of inheritance, Aventus fosters code reusability, promotes a modular design approach, and enhances developer productivity. Whether you're building simple UI elements or sophisticated application components, Aventus offers a solid foundation for structuring and organizing your codebase.

To delve deeper into the world of Aventus and explore its vast array of features and capabilities, we invite you to visit the official Aventus website at [https://aventusjs.com](https://aventusjs.com). There, you'll find comprehensive documentation, tutorials, and examples to help you harness the full potential of Aventus and unlock new possibilities for web development.

Thank you for joining us on this journey through the realm of web component inheritance in Aventus. We hope this article has provided you with valuable insights and inspiration for your future projects. Happy coding with Aventus!