Component


About

Component - the main concept of the framework. Almost the entire structure built using the framework is based on a component approach.

The Component itself is a specific fragment of the site, be it a button, a list, or a text block, etc.

Class function

const newComponent = component("new-component", "HTML");

Arguments

The Component includes three arguments, the first of which is the value of the "data-cample" attribute (selector), the second is an HTML template containing string interpolation, and the third is a settings object.

selector

The selector is the value of the "data-cample" attribute of the template in which the component will be rendered. For example, if the selector is set to "new-selector", then the HTML "template" into which the component will be rendered will look like this:

<template data-cample="new-selector"></template>

It is worth noting that there can be as many "template" tags on a site as you like (within the memory of the machine where the site is located). That is, if there are 100 "templates" with the "new-component" attribute, then 100 components will be rendered.

template

A template is essentially a string that will be rendered in the "template" with attribute "data-cample". This string provides for string interpolation, which means replacing the content in double curly braces with the template corresponding to it in javascript HTML. An example of a template with string interpolation:

("new-component", 
`<div class="component">
    { {component_text} }
</div>`,
{
    data:()=>{
        return {
            component_text:"Text"
        }
    }
})

Usually, the values for string interpolation in a template are located in the options object, and more specifically in the data function. Options object will be discussed in the next paragraph.

options

The options object describes the scripts, attributes, data, styles of the component, etc. Each of the listed properties describes a property of an object.

script

An array with two values is passed to the script object property, the first of which is a function that accepts the values of the component element, current data, as well as dynamic data functions and imported data and is triggered depending on the settings, and the second value is a script settings object that accepts one argument : "start". This argument takes three values: “beforeLoad”, “afterLoad” and undefined. This setting describes when the script function should be executed before or after the component is loaded. If the values are not defined, the function will be loaded after. Example script:

{
    script: [
        ({ element, functions, currentData, importedData }) => {
        element.addEventListener("click", () => {
            console.log(elements.component);
        });
        const updateFunction = (e) => {
            functions?.updateText((data) => {
                return "newText";
            });
        };
        document.addEventListener("onload", updateFunction);
            console.log(data);
        },
        {
            start: "afterLoad",
        },
    ],
    data: () => {
        return {
            dynamicText: "Text",
        };
    },
    dataFunctions: {
        updateText: "dynamicText",
    },
}

Also, the framework supports a script without an array. That is, a function can also be passed to a value.

{
    script:({ element, functions, currentData, importedData })=>{
        console.log("123");
    }
}

The function is running after loading by default.

attributes

The attributes property contains an object of the HTML attributes and their values that will be processed in the HTML "template". An example of the attributes:

("new-component", 
`text`,
{
    attributes:{
        id:"id"
    }
})

In this example, the component with the "new-component" selector will be assigned an "id" attribute with the value id.

data

The data property contains a function that returns an object with properties that are processed in the template using string interpolation. These properties accept values with any data type. The function takes an object with imported data as arguments.

("new-component", 
`<div class="component">
    { {component_text} }
    { {component_array_texts} }
    { {dynamicData.value} }
</div>`,
  {
    data: ({ importedData }) => {
      return {
        component_text: "ComponentText",
        component_array_texts: ["Text"],
        dynamicData: {
            value:"Data"
        },
      };
    },
  };
);

All values are passed through the String() function before being assigned. Also, if the value is an object, then its properties can be accessed through a dot, as is done in vanilla js.

dataFunctions

The dataFunctions property is intended for creating data update functions. That is, this property accepts an object of type "function name": "the first data keyword without dots".

{
    data: () => {
        return {
            component_text: "ComponentText",
        };
    },
    dataFunctions:{
        setComponentText:"component_text"
    }
}

These functions are passed in function arguments in a script property. More precisely, in the object in the “function” property. And also, they are available in the functions property.

functions

The functions property takes in an object of properties whose value is an array with the function and the name of the updating function from dataFunction, as in export in functions.

{
    data: () => {
        return {
            component_text: "ComponentText",
        };
    },
    dataFunctions:{
        setComponentText:"component_text"
    },
    functions: {
        updateComponentText: [
          (setData, event) => (arguments) => {
            event.preventDefault();
            setData(() => "123");
          },
          "setComponentText",
        ],
    }
}

In the array, the first function will receive the data updating function from dataFunctions as the first argument and the Event object as the second argument, and all the arguments that were specified either in the template or in the script object will be passed to the second function. Using a closure, the second function will have access to both the arguments that were passed and the updating function.

In template, a call to such a function will look like this:

<div class="{ {component_text} }">
    <div id="{ {component_text} }">
        <div :click={ {updateComponentText(setComponentText)} } >{ {setComponentText} }</div>
    </div>
</div>

As arguments in this form, the function takes only property names from the data property. All event names come from vanilla in javascript, as if the addEventListener method was applied to the element.

In the framework, the "click" event is synthetic.

import

The import property sets the "data-cample-import" attribute. This attribute specifies data to import specific exported data. An example of the import:

import:{
    value:["text"],
    exportId:"textId"
}

For example, if a component was given import data in other components, then the import object will overwrite them in the tag attribute.

value

The value property on the import object specifies a list of exported values that will be imported into the component. An example of the value:

{
    value:["text", "text1"]
}

In this example, two values are passed to the "data-cample-import" property: "text" and "text1".

exportId

In order to understand which component to import data from, the import object provides such a property as exportId. This property is set in the component that exports the data. It is set either in the options object. An example of the exportId:

{
    exportId:"textId"
}

In this example, the data will be imported from a component that will have its exportId set to "textId".

export

Thanks to the export property, you can send data and functions from the component. The value for this property is an object with properties that take the value of an object consisting of two properties - "data" and "functions". The data object contains the data from the "data" property, the functions object contains the data from the "functions" property.

{
    data: ({ importedData }) => {
        return {
            component_text: "Text",
        };
    },
    dataFunctions: {
        updateText: "component_text",
    },
    export: {
        dataToExport: {
            data: {
                text: "component_text",
            },
            functions: {
                setText: [
                    (setData) => (txt) => {
                        setData(() => txt);
                    },
                    "updateText",
                ],
            },
        },
    }
}

The data property of the "dataToExport" object specifies the name of the data from the properties of the "data" object and gives them a new key for export, the "functions" property in the same object specifies an array, the first argument of which is a function with a closure, and the second is the name of the exported function from "dataFunctions" object. In the first array argument, the argument of the first function is the data update function that was specified in the second array argument. The argument of the second function is the data that changes.

In order to export data to a specific component, in addition to exportId, needed to "pass an object" to the value of the "data-cample-import" attribute of the desired component.


`<div class="component">
    <template data-cample-import="{ { {dataToExport} } }"
    data-cample="another-component"></template>
</div>`

The property for the imported object can be different, in this example the property is the "dataToExport" property.

exportId

The exportId property specifies the export identifier, by which the component will "determine" where to get the data from. An example of the exportId:

{
    exportId:"textId"
}

In this example, to export specific data, "exportId" is set with the value "textId".

style

The style property contains a string that is inserted into the HTML style tag. This string is the stylesheet syntax, i.e. cascading style sheets syntax. An example of a style:

("new-component", 
`<div class="component">
    Text
</div>`,
{
    style:`
        .component{
            width:100px;
            height:100px;
        }
    `
});

Component styles are rendered in the style tag, thus it is possible to create styles in one component for another.

values

The values property takes the value of an object whose property has a value of an object that generates dynamic data depending on a condition.

values: {
    selectedValue: {
        "currentData.select === currentData.true":"selected",
        "!(currentData.currentClass && currentData.false) == currentData.anotherProperty":["class1","{ {currentData.class2} }"]
    },
}

In this example, only the values from the data property are used in the conditions; in their values, you can write both regular text and text with string interpolation. If the value is a string, then if true, the value will be this string, and if false, then "". If the value is an array of two strings, then it works like a ternary operator, when if true is the first value, if false is the second value.

**Also, it's worth noting that difficult conditions are still being tested! The code may produce other values of true or false! It is highly recommended to use simple conditions with one or more operators!**
HTML before
<div class="class { { [selectedValue] } }">
    { { [selectedValue] } }
</div>
HTML after
<div class="class selected class1">
    selected
</div>

Also, it's worth noting that in string interpolation, values are "passed as an array". The key to the dynamic string in this example is the "selectedValue" value.

trimHTML

Depending on the value of the trimHTML property, the javascript trim() method is applied to the HTML string.

{
  trimHTML:false
}

This will avoid the errors associated with rendering a single Element in the component, but also the HTML may not be displayed correctly.

Example code

new Component(
"new-component",
`<div class="{ {[selected]} } component" :click={ {setText1(component_text)} }>
    { {component_text} }
    { {dynamicData} }
    <template data-cample-import="{ { {exportData} } }"
    data-cample="another-component"></template>
</div>`,
{
    script: [
    ({ element, functions }) => {
        console.log(element);
        const updateFunction = (e) => {
        functions?.updateText((data) => {
            return "newText";
        });
        };
        document.addEventListener("onload", updateFunction);
    },
    {
        start: "afterLoad",
    },
    ],
    attributes: {
        id: "id",
    },
    data: ({ importedData }) => {
        return {
            component_text: "Text",
        };
    },
    style: `
        .component{
            width:100px;
            height:100px;
        }
    `,
    dataFunctions: {
        updateText: "component_text",
    },
    functions: {
        setText1: [
            (setData, event) => (txt) => {
                event.preventDefault();
                setData(() => txt);
            },
            "updateText",
        ],
    },
    export: {
        exportData: {
            data: {
                text: "component_text",
            },
            functions: {
                setText: [
                    (setData) => (txt) => {
                        setData(() => txt);
                    },
                    "updateText",
                ],
            },
        },
    },
    values: {
        selected: {
            "!!component_text": "selected"
        },
    },
    exportId: "textId",
    import: {
        value: ["text1"],
        exportId: "textId1",
    },
    trimHTML: false,
}
);

Component table

Arguments
Name Usage Type
selector The value of the "data-cample" property of the template tag into which the component will be rendered. SelectorType
template HTML rendering template including string interpolation. string
options Object options. ComponentOptionsType | undefined

Articles