copied to clipboard

Elements

Elements are simple function calls of ambient global variables.
All standard HTML5 elements except var (for obvious reasons) are available.

Element Options

The first parameter you pass to an element can either be another element,
or an options object. If the first parameter is an element, then that element is prepended
to the elements children; and the element will have no options.

h1 ("I'll have 1 child, and no options!"),
h1 ("I'll have 2 children, and no options!", "I am the second child."),
[
    {
        tag: "h1",
        options: {},
        children: ["I'll have 1 child, and no options!"],
    },
    {
        tag: "h1",
        options: {},
        children: [
            "I'll have 1 child, and no options!",
            "I am the second child!",
        ],
    }
]

This is done purely for syntax reasons. For example,
I think it's nicer to write b("bold.") than b({}, "bold.")

An options object may specify any attribute, and that attributes value may be a string,
number or boolean.

div ({
    id: "my-element-id",
    customAttribute: "SUPER-IMPORTANT",
    innerText: "Pokemon Platinum was peak Pokemon.",
})

Important Considerations

    1. You should enter attributes as camelCase. They will be converted into kebab-case upon compilation.

    2. Unlike in React, you'll want to use class for class names, rather than className.

    3. on[Event] handlers can only be State Object Attributes

    4. The attributes key and bp are reserved by Elegance.

    5. innerText prepends its own value to the elements children.

    6. innerHTML sets the elements children to its value.

Children

The rest of the values passed in to an element call, will be the elements children.
Strings, numbers, booleans, arrays, and other element calls, are all valid children.

div (
    1,
    true,
    "Hello World!",
    ["Apple", "Banana"],
    ...someArray.map((value, index) => p(index)),
)

Object Attributes

Object attributes, simply put, are a type of option for elements.
Any Element Option with type object is considered an Object Attribute.
They are used to tell the compiler to do special things with the option, instead of just serializing it.

For brevity, we shorten object attributes to [TYPE]OA.
So, a State Object Attribute -> SOA.

Object Attributes are required to specify a type property.

export enum ObjectAttributeType {
    GENERIC = 0,
    STATE = 1,
    OBSERVER = 2,
    EVENT_LISTENER = 3,
    REFERENCE = 4,
}

Now, 99% of the time, you won't craft OAs manually.
Instead, you'll use a helper function, which returns an OA of a specified type.

For example, the observe() function, returns something like this.

{
    type: ObjectAttributeType.OBSERVER,
    initialValues: refs.map(ref => ref.value),
    update: update,
    refs: refs.map(ref => ({
        id: ref.id,
        bind: ref.bind,
    })),
};

Then, the compiler; when it encounters an OA that is of type ObjectAttributeType.OBSERVER
Calls the update function, sets the return value as the attribute value, and puts the OOA into the page_data.

This is really all you need to know about OAs, they are just object values for attributes,
which the compiler treats differently.