APL Style Definition and Evaluation (APL 1.0)


(This is not the most recent version of APL. Use the Other Versions option to see the documentation for the most recent version of APL)

A style is a named entity that defines a set of visual properties. You can use the style to consistently set those properties on a component. Styles can include conditional logic and can use component state. For example, a style could change text color depending on whether the component's state is checked.

Style definitions

A style definition specifies the name of the style, a list of one or more parent styles to inherit from, and an ordered list of conditionally-applied property definitions. Here is a style definition title suitable for use by the Text component. It sets the size of the font and the color. The color changes based on the state of the Text component and current theme.

  "styles": {
    "baseText": {
      "values": [
        {
          "fontFamily": "Amazon Ember",
          "color": "${viewport.theme == 'dark' ? 'white' : 'black' }"
        },
        {
          "when": "${state.karaoke}",
          "color": "blue"
        }
      ]
    },
    "title": {
      "extends": "baseText",
      "values": [
        {
          "fontWeight": 700,
          "fontSize": "${viewport.height > 400 ? 30 : 25}"
        }
      ]
    }
  }

For example, the title style on a device with a large viewport, dark theme, and focused state evaluates to:

{
    "fontFamily": "Amazon Ember Display",
    "color": "blue",
    "fontWeight": 700,
    "fontSize": 30
}
Which properties can you set in a style?

Not all component properties can be set with styles. See Styled Properties for a reference to all styled properties across all components. For an individual component, note the table of available component properties. Properties that you can set in a style for that component are indicated with "Yes" in the "Styled" column of the table. For example, see the Text properties table and note that all properties except text are styled.

Definition properties

Each style definition has the following properties.

Property Type Required Description
description String No A description of this style
extend Array of style names No List the styles that this style inherits from. Order is important; later items override earlier.
values Array of VALUE objects No An array of objects 

The extend array contains an ordered list of styles that this style inherits from. The access property controls whether or not this style is available outside of the defining package.

The values array contains an ordered list of value objects to apply. Each value object has the form:

{
  "when": EXPRESSION,
  NAME: VALUE,
  NAME: VALUE,
  :
}

The when property is optional and defaults to true if it is not defined. The defined properties are expected to be the names of valid styled properties (they are ignored if they are invalid names). The data-binding context for the when clause contains the viewport, environment, resource definitions, and styles that appear earlier in the document or in imported packages.

Style evaluation

Component evaluation

Individual components have state. The following state properties are defined:

Property Definition
checked The component has been checked or toggled on
disabled Component has been disabled (many components have a "disabled" property) 
focused Component has the keyboard input focus
karaoke Used during speech read-out
pressed Mouse or touch input is active

The component states are set during component creation and may change based on user interaction, such as by touching the screen or using a keyboard, or with commands. For example, the TouchWrapper component responds to touch or keyboard events by setting the pressed state. The combination of component states and styles is used to change the visual appearance of a component.

Changing the state of a component does not change the state of the children in a component unless you set the inheritParentState property. Here is a sample Text component that changes color when it is pushed:

Definition of a style:

"textStylePressable": {
  "values": [
    {
      "color": "white"
    },
    {
      "when": "${state.pressed}",
      "color": "green"
    }
  ]
}

Use of the style in a layout:

{
   "type": "TouchWrapper",
   "item": {
     "type": "Text",
     "inheritParentState": true,
     "style": "textStylePressable",
     "text": "Push Me!"
   }
}

Evaluation of a style

Each component references a named style either explicitly or implicitly (device runtimes have default styles for each component). The style evaluation occurs in a restricted data-binding context with just the viewport,state, and resource definitions.

The calculated style is a function of the viewport, resources, and state. The calculation algorithm can be approximated with this pseudo-code:

function _calcInternal(style, context):
  result = {};

  // Walk the extend array
  foreach style.extend as name:
    result += _calcInternal( getStyleByName(name), context)

  // Walk the values array
  foreach values as value:
    if evaluate(value.when):
      result += evaluateEach(value)

  return result

function calculateStyle(style, context, state):
  workingContext = extendContext(context, { state: state })
  return _calcInternal(style, workingContext)

The extend array is calculated first, followed by the values blocks (in order).


Was this page helpful?

Last updated: Nov 28, 2023