Tutorial: Elements, Properties, and Comments

Elements, Properties, and Comments

Elements

A Shui file (or document) consists of a tree of nested elements. To create an element, put its class name with curly braces.

Document { }

Many elements may contain child elements. These are placed within the curly braces of their parent. It is usually a good idea to indent the children by spaces in order to make the code more readable.

Document {

    Label { }

    Box {
        Label { }
    }

}

Every Shui file consists of exactly one root element, which in turn may contain child elements. The root element of the main file of a web UI must be Document for things to appear on screen.

Properties

Elements are parameterized by properties. In order to assign a value to a property, name that property inside its element, and put a colon (:) followed by the property's value.

Label {
    fontSize: 16
    color: "blue"
    text: "I am a label."
}

The data type of the property is determined by the type of the assigned value.

You may put several properties on a single line by separating them with semi-colons (;).

Label { color: "red"; text: "I am a red label." }

Strings quoted with """ instead of " may span multiple lines and may contain " characters.

Label {
    text: """This is a 
             multiline string
             containing "quotes"."""
}

Custom Properties

You may define custom properties on any element by using the property keyword before the assignment.

Label {
    property myVeryOwnProperty: 42
}

Identifiers

The id property is a special property for assigning a document-unique name to an element. Its value must be a valid identifier consisting of alphanumeric characters and the underscore (_) only. Do not put quotes around the identifier.

Document {

    Label {
        id: label1
    }

    Label {
        id: label2
    }

}

Identifiers are used to reference elements or their properties. To access a property's current value, put a dot (.) between the identifier and the property name.

Document {

    Label {
        id: label1
        text: "I am a label."
    }

    Label {
        text: label1.text
    }

}

You cannot reference an element's identifier as a property. In other words, this would not work:

Label {
    text: label1.id
}

Typed References

References starting with this followed by an element type, e.g. thisDocument reference the nearest ancestor in the hierarchy of the given type.

Document {

    title: "This is the title text."

    Label {
        text: thisDocument.title
    }

}

Property Bindings

Instead of values you may also assign JavaScript expressions to properties.

Box {
    width: 3 * 128
}

You may also reference other properties within a JavaScript expression.

Document {

    Box {
        id: box1
        width: 256
        height: width
        color: "green"
    }

    Box {
        width: Math.max(box1.width, 128)
        height: width
        color: "red"
    }

}

Whenever one of the referenced properties changes, the expression gets re-evaluated to update the property's value.

Attention: Be careful not to build circular references this way. While Shellfish detects them at runtime and breaks the infinite update loop, they print an error message to the console and serve no purpose.

References consisting of only the property name without an element identifier access the element they are used within, or one of its ancestors if the property was not found.

Box {
    property foo: "bar"

    Box {

        Label {
            text: "Value of foo: " + foo
        }

    }
}

Parent and Children

The elements placed inside an element are child elements. Each child element references the element it is contained in by the parent property.

Box {
    height: 100

    Label {
        text: "My parent's height is: " + parent.height
    }
}

The method children() of the parent element returns the list of children.

Box {
    height: children().length * 32
    color: "green"

    Label { text: "1" }
    Label { text: "2" }
    Label { text: "This box has " + parent.children().length + " children." }
}

Comments

Comments in Shui are written in JavaScript style (i.e. C++ style).

// makes all characters right to it ignored until the end of the line.

Box {
    width: 42 // this is a comment
}

/* and */ are used to make everything inbetween ignored, even when spanning multiple lines.

Box {
    /* This is a
       multiline
       comment. */
}