Welcome to this quick start tutorial for Live Elements. These chapters will guide you through most of the concepts in Live Elements and show you how to make the most out of the language.
We will go through:
To practice all these concepts, we're going to use the Live Elements playground at play.liveelements.io.
If you want, you can also setup the playground offline. Simply install lvweb
from live-elements-web-cli
package and use it to generate and run the playground on localhost:
mkdir playground
cd playground
npm i live-elements-web-cli # install lvweb
npx lvweb init --template playground # create the playground
npx lvweb serve # run the playground
The playground should now be running at localhost:8080.
If you have any trouble installing lvweb
, you can checkout the installation page. It offers more information on installation and troubleshooting.
In the top left corner of the playground page, you will find the 'Open' icon. There's different projects you can open, they show different use cases with Live Elements.. We're going to open the Application (Console) project which is a template for a simple console application.
This will open the Index.lv
file in the editor, with the following contents:
import live-web
component App < Application{
run: () => {
console.log('Application is now running.')
}
}
We're going to go into more detail about the file structure, but for now, just note that the file imports live-web
module. It's where the Application
component is defined. Then, a new component is declared in the file, App
component, which inherits from Application
:
component App < Application{
// ...
}
Components in Live Elements are similar to classes in javascript, they include most of the functionality from classes, but they have additional features, which we will cover in this guide. Components inherit from other components, which works similarly to class inheritance, and they use this inheritance symbol: <
. Components can also have properties, in this case the run
property is assigned by the App
component. The run
property is a function that's run by the playground when it loads the Index.lv
file. Inside the run
function, we can write javascript and live elements code.
We can already see the function was run in the playground, as we see the message Application is now running.
in the console. To run the application again, we can either click on the 'compile' button in the top bar, or save the file after modifying it. Saving the file will trigger a compilation automatically. The file can be saved using cmd+s
on Mac or ctrl+s
on a pc.
Most of the coding in this part will be inside the run
function.
We've mentioned above that components are similar to javascript classes, and they inherit from other components. All components actually inherit the BaseElement
component, similar to how all classes inherit the Object
class in javascript.
A component inheriting directly from BaseElement
does not need to write that implicitly:
component MyComponent{}
// is the same as
component MyComponent < BaseElement{}
Components are created using the curly braces:
let a = MyComponent{} // a is now assigned with an instance of MyComponent
You can try this out in the run
function:
import live-web
component App < Application{
run: () => {
component MyComponent{}; // declare MyComponent
let a = MyComponent{}; // create MyComponent
console.log('New component created: ', a)
}
}
You should now see: New component created: [object Object]
.
Notice we've mixed javascript code with live elements code. let a
for example is in javascript, and MyComponent{}
is in live elements. Live Elements simply acts as an extension to javascript, and the 2 languages can be mixed freely between each other.
Components can declare properties like this:
component MyComponent < BaseElement{
number x : 20
}
const a = MyComponent{}
console.log(a.x) // 20
Properties in components bind automatically, meaning if a property references another, then changes to that other property will also update the current one. The example below shows property y
referencing property x
. This means that whenever property x
changes, property y
will also change:
import live-web
component App < Application{
run: () => {
component MyComponent < BaseElement{
number x : 20
number y : this.x
};
const a = MyComponent{}
console.log(a.y) // Output: 20
a.x = 30
// Both x and y are now 30
console.log(a.x, a.y) // Output 30 30
}
}
Expression assigments also bind properties:
import live-web
component App < Application{
run: () => {
component MyComponent < BaseElement{
number x : 20
number y : 30
number z : this.x + this.y // z is now bound to x and y
};
let a = MyComponent{}
console.log(a.z) // Output: 50
a.x = 30
// z is now (x + y), which is 60
console.log(a.z) // Output: 60
}
}
Components can have their properties assigned during creation:
component MyComponent < BaseElement{
number x : 20
number y : 30
};
let a = MyComponent{
x : 10
y : 20
}
console.log(a.x + ' ' + a.y) // Output: 10 20
Bindings also work when assigning through creation:
let a = MyComponent{
x: 10
y: this.x
};
a.x = 20
console.log(a.y) // Output: 20
Try it out in the playground:
import live-web
component App < Application{
run: () => {
component MyComponent < BaseElement{
number x : 20
number y : 30
};
const a = MyComponent{
x: 10
y: this.x
}
a.x = 20
console.log(a.y) // Output: 20
}
}
Constructors are declared similarly to javascript class constructors:
component MyComponent{
constructor(x:number){
super()
this{}
console.log("Created with x = " + x)
}
}
The only difference is the required call to super
and to this{}
before adding any other instructions. The call to this{}
initializes all the properties, events and bindings of the component.
Creating an object using a constructor with arguments can be done by using the dot (.
) after the component name, followed by the list of parameters in paranthesis, and followed by the assignments in curly braces:
// without assignment
const b = MyComponent.(100){} // Output: Created with x = 100
// with assignment
const c = MyComponent.(100){ prop : 15 } // Output: Created with x = 100
The full playground version:
import live-web
component App < Application{
run: () => {
component MyComponent{
constructor(x:number){
super()
this{}
console.log('Created with x = ' + x)
}
};
const b = MyComponent.(100){} // Output: Created with x = 100
}
}
Components with constructors that have a single argument of type string
can be created using the following notation:
let a = ComponentName`argument`
// instead of the longer version
let a = ComponentName.('argument'){}
See how MyComponent
is created below:
import live-web
component App < Application{
run: () => {
component MyComponent{
constructor(text:string){
super()
this{}
console.log('Initialized with text = ' + text)
}
};
// Standard notation
let a = MyComponent.('Hello'){} // Output: Initialized with text = Hello
// Shortcut
let b = MyComponent`Hello` // Output: Initialized with text = Hello
}
}
A component can accept children by configuring a default
property called children
:
component MyComponent{
default children
};
A component with a default
property can have component objects created directly in it's body. The objects will be assigned as a list to the default
property:
import live-web
component App < Application{
run: () => {
component MyComponent{
default children
};
let a = MyComponent{
BaseElement{} // child 0
BaseElement{} // child 1
}
// Output: Total children: 2
console.log('Total children:', a.children.length)
}
}
A component supports a single default
property. The default
keyword also acts as a placeholder for the Array<BaseElement>
type. The following code:
component MyComponent{
Array<BaseElement> children
}
let a = MyComponent{
children: [BaseElement{}, BaseElement{}]
}
Is the same as:
component MyComponent{
default children
}
let a = MyComponent{
children: [BaseElement{}, BaseElement{}]
}
However, since the children
property is also declared as default
, we can also assign MyComponent
children
as such:
let a = MyComponent{
BaseElement{}
BaseElement{}
}
This chapter went through some of the basics on Live Elements components. We can now start looking at how this a applies to creating webpages in the following chapter. We will also cover more things on components like events, functions, listeners and others, but we will introduce them as we progress.