Within the Loki architecture, we are not just simply referring to Alpine components. Instead, we talk about components, component data definitions, component types and component partials.
Because Loki focuses heavily upon the reusability of code, how Alpine components come to being depends upon 4 things:
x-data
. With Loki, component data is always defined with Alpine.data()
and the definitions are placed preferably in the XML layout container loki-components
(which places them at the bottom of the page)....foobar
). Whenever this happens, the destructured object that is imported into the regular object is referred to as a component partial. Component partials are comparable to mixins or traits.As an example, there is a checkout component named LokiCheckoutSteps
(which resembles the component property id
and the x-title
attribute. It is initiated with x-data="LokiFieldComponent"
which shows that there is a component data definition LokiFieldComponent
somewhere on the page as well.
<div id="loki-checkout-steps" x-data="LokiFieldComponent" x-title="LokiCheckoutSteps">
<script x-ref="initialData" type="text/x-loki-init">
{"id": "LokiCheckoutSteps", "name": "LokiFieldComponent", /* ... */}
</script>
</div>
The general data definition LokiFieldComponent
is used in numerous components and defined with the following:
document.addEventListener('alpine:init', () => {
Alpine.data('LokiFieldComponent', () => ({
...LokiFieldComponentType,
}));
});
As you can see, the data definition of LokiFieldComponent
fully depends upon an object LokiFieldComponentType
(which we call a component type). This object looks like the following):
const LokiFieldComponentType = {
...LokiComponentType,
fieldName: '',
fieldValue: null,
/* ... */
}
It is a plain object that uses ES6 destructuring to borrow properties from a more generic LokiComponentType
and then add its own properties on top of this. The LokiComponentType
is also known as a component type.
In the case, there is no usage of component partials here.
An example for a component partial could look like the following:
const LokiExampleComponent = {
...LokiComponentType,
...LokiTabComponentPartial,
}
In this case, a custom component LokiExampleComponent
is created based on top of the component type LokiComponentType
and the component partial LokiTabComponentPartial
. As you can see, using a component type and a component partial is the same.
The difference between a component type and a component partial is that with the import of a component type (...LokiComponentType
) you already have a full-blown component, while the import of a component type (...LokiTabComponentPartial
) you only get specific behaviour.
At this moment, the following component partials exist:
LokiTabComponentPartial
for managing tabs;LokiModalComponentPartial
for managing modal popups;