States

Role

A state is a set of properties values that differs from the default configuration.

The states are available on views and are defined by using the states class keyword.

Expected Use

Declaration

A state declare values for properties of the view or of its children.

import View from "@View";
import TextPrimitive from "@TextPrimitive";

export default View.declare("WelcomeHomeInfoView", {
    children: {
        titleText: {
            class: TextPrimitive,
            text: ({parent}) => parent.title
        },
        genreText: {
            class: TextPrimitive,
            text: ({parent}) => parent.genre
        }
    },
    states: {
        slided: {
            "titleText.y": -28,
            "titleText.opacity": 0,
            "genreText.y": -56,
            "genreText.opacity": 0
        },
        focused: {
            scale: 1.2
        }
    }
});

Advanced use

Change state

view.setState("slided")

// view.titleText.y = -28
// view.titleText.opacity" = 0
// view.genreText.y = -56
// view.genreText.opacity" = 0

Compounded states

A compounded state is the aggregation between multiple states. The states are compounded by using the & character.

import View from "@View";

export default View.declare("WelcomeHomeInfoView", {
    properties: {
        x: 0,
        y: 0
    },
    states: {
        "stateA": {
            x: 20
        },
        "stateB": {
            y: 50
        }
    }
});

view.setState("stateA");
// x = 20, y = 0
view.setState("stateB");
// x = 0, y = 50
view.setState("stateA&stateB");
// x = 20, y = 50

Conflicts

If a state part of a compounded state defines the same property, there is a conflict.

In that case, you must resolve the conflict by hand by defining the compounded state in your states.

import View from "@View";

export default View.declare("WelcomeHomeInfoView", {
    properties: {
        x: 0,
        y: 0
    },
    states: {
        "stateA": {
            x: 20,
            opacity: 0
        },
        "stateB": {
            opacity: 1,
            y: 50
        },
        "stateA&stateB": {
            opacity: 1
        }
    }
});

In that example, the property opacity is in conflict : the stateA&stateB definition resolves the conflict.

Caution

Order is not important, you can declare stateA&stateB or stateB&stateA.

Append a state

You can append a state by doing a setState("&stateName") : it will create a compounded state with the current state.

import View from "@View";

export default View.declare("WelcomeHomeInfoView", {
    properties: {
        x: 0,
        y: 0
    },
    states: {
        "stateA": {
            x: 20
        },
        "stateB": {
            y: 50
        }
    }
});

view.setState("stateA");
// view is in state stateA
// x = 20, y = 0
view.setState("&stateB");
// view is in state stateA&stateB
// x = 20, y = 50

Remove a state

You can remove a state by doing a setState("!stateName") : it will remove the state from the current state.

import View from "@View";

export default View.declare("WelcomeHomeInfoView", {
    properties: {
        x: 0,
        y: 0
    },
    states: {
        "stateA": {
            x: 20
        },
        "stateB": {
            y: 50
        }
    }
});

view.setState("stateA&stateB");
// view is in state "stateA&stateB"
// x = 20, y = 50
view.setState("!stateB");
// view is in state stateA
// x = 20, y = 0

Delay

Apply the properties values after the delay. If a transition is set for this property, it will override the delay (see Transitions).

view.setState("slided", {delay: 250})

// view is in state "slided"

// ~250ms later
// view.titleText.translateY = -28
// view.titleText.opacity" = 0
// view.genreText.translateY = -56
// view.genreText.opacity" = 0

Caution

Even if setState has a delay, the view goes into the state slided as soon the setState() method is called.

The delay is synchronous with the rendering loop, so it can have a delta.