Theme
From color schemes to typography, widgets, and transition options, our comprehensive range of theme elements allows you to effortlessly personalize your app. Discover how themes can transform your online presence, create a cohesive brand identity, and provide a delightful user experience. Unlock the full potential of your app with our versatile and user-friendly theme customization features.
Kitchen Sink Example (opens in a new tab)
Where to find it ?
You can find the theme on Left-Side of the panel in ensemble studio after you have selected your App.
Checking and Switching Themes in Javascript
var themes = app.themes; //returns a list of all configured themes
var currentTheme = app.theme; //currently applied theme
app.theme = 'newTheme'; //change themes dynamically. The theme name must be in the list of Themes in the theme definition.
In the following EDL, a DropDown
widget is bound to the list of themes
that have been configured in the app and allows user to swtich from one theme to another.
Example:
Bind the themes
to a dropdown and let user switch themes from all the available themes.
- Dropdown:
label: Pick a Theme
items: ${app.themes}
value: ${app.theme}
onChange:
executeCode:
body: |
app.theme = this.value;
Savings themes in storage so they can be applied across application sessions
A common requirement from theming is to be able to persist a theme that user has selected across multiple application sessions i.e. even when the user kills the app and relaunches, the theme s/he selected should automatically apply. Ensemble provides that capability by storing themes in local storage.
At application startup time, Ensemble platform checks if there is a saved theme and if that theme exists in the list of theme definitions. If both conditions are true, it automatically applies the saved theme instead of the default theme configured in the app.
Application developers have the following functions available to them.
//save theme in storage, this will automatically be applied by the platform on startup
//note that saveTheme does NOT apply a theme, it merely saves it. use app.theme = 'myNewTheme'; to change themes dynamically,
app.saveTheme('myNewTheme');
//retrieve the saved theme
var savedTheme = app.getSavedTheme(); //there can only be one saved theme
//or remove the saved theme from storage
app.removeSavedTheme();
Text Styles are automatically inherited unless overriden
All text styles (for example - fontSize
, fontFamily
, color
etc) can be defined at the View
, Column
, Row
or any of the top widget level and will automatically be inherited by all Text
widgets. Note that labels for Button
etc do not inherit these styles.
Example:
View:
className: topView
#rest of your screen definition
And over in your Theme
Styles:
.topView:
backgroundColor: ${Colors.gray['200']}
textStyle:
fontWeight: ${Typography.fontWeight['700']}
fontSize: ${Typography.fontSize['xl']}
All Text
in the screen will inherit these text styles. You can specify the style at the View
node and then all Text widgets across your whole app would inherit those text styles
Parts of a Theme
- Tokens (optional)
- Styles (in precedence order)
- Inline - specified directly on the widget
- ID based - specified with
#
before the name in the Theme.Styles - Style Classes - specified as
className
attribute on a widget. One or more space delimited classes - Widget type - specified for the widget type such as Button in the Theme.Styles
- Inherited from parent - these are limited to
textStyle
only (see above)
Here's an explanation of the different parts of a theme:
1. Tokens (Optional):
Tokens are named collections of values typically used for colors, fonts, and spacing. They provide a way to define reusable values across your theme and avoid code duplication. These tokens are then used inside the Styles
with the expression syntax, for example ${Colors.gray['200']}
Example:
Light:
label: Light Theme
description: This theme turns everything light as in white background and is default
inheritsFrom: Common
Tokens:
Colors:
teal:
'900': '#014451'
'800': '#05505C'
'700': '#036672'
'600': '#047481'
'500': '#0694A2'
'400': '#16BDCA'
'300': '#7EDCE2'
'200': '#AFECEF'
'100': '#D5F5F6'
'50': '#EDFAFA'
Styles:
Button:
borderRadius: 20
.submit:
backgroundColor: ${Colors.teal['800']}
labelStyle:
color: white
fontFamily: ${Typography.fontFamily}
2. Styles (Precedence Order):
Styles define how different UI elements will appear. Ensemble applies styles based on their precedence, with higher precedence styles overriding lower ones. Here's the order of precedence, from highest to lowest:
- Inline Styles: Styles defined directly on the widget using the
style
attribute. - Style Classes: Styles defined in the theme and applied to a widget using the
className
attribute (space-separated list of classes). - ID-based Styles: Styles defined in the theme using an ID selector (preceded by
#
). - Widget Type Styles: Styles defined for a specific widget type (e.g.,
Button
).
Example of Styles defined in a Theme:
Light:
Styles:
# ID-based style
'#heading':
fontSize: 24
fontWeight: bold
# Widget type style
Button:
backgroundColor: ${Colors.primary}
color: white
# Style class
.error:
color: red
Example of Inline styles and specifying classes
Button:
styles:
backgroundColor: red
className: commonButton submitButton #here two classes are applied in order i.e. the styles defines in the list of classes are merged in the order they are specified.
Specificity:
Similar to CSS, styles in Ensemble with higher specificity will override those with lower specificity. Specificity is determined by the number and type of selectors used in the style definition. Inline styles and styles specified by the ID-based styles have the highest specificity, followed by classes and then widget type styles.
By understanding the different parts of a theme and how inheritance and specificity work, you can create well-structured, maintainable, and reusable themes for your Ensemble applications.
Theme Inheritance in Ensemble
Ensemble allows you to create reusable and organized themes using inheritance, similar to how CSS works. This lets you define common styles in a base theme and then have other themes inherit and modify those styles as needed.
Benefits of Theme Inheritance
- Reduces code duplication: Define common styles once in a base theme and avoid repeating them in other themes.
- Improved maintainability: Makes changes to common styles easier to manage as they are centralized in the base theme.
- Theming hierarchy: Build a clear hierarchy of themes, making it easier to understand how styles are applied.
How Inheritance Works
- Base Theme: Define a theme (e.g.,
Common
) containing the styles you want to share with other themes. You can define multiple base themes - Inheriting Theme: Define another theme (e.g.,
Light
) and specify the base theme it inherits from using theinheritsFrom
property. A base theme may inherit from another theme forming a chain - Overriding Styles: The inheriting theme can override any styles from the base theme by defining the same styles with different values.
Example
Here's an example demonstrating theme inheritance:
Common Theme:
Common:
label: Common theme
Tokens:
Colors:
primary: '#0077B8'
gray:
'200': '#f2f2f2'
'300': '#e0e0e0'
Styles:
.topView:
backgroundColor: ${Colors.gray['200']}
Button:
borderRadius: 20
backgroundColor: red
Light Theme (inherits from Common):
Light:
label: Light Theme
description: Light theme with white background
inheritsFrom: Common
Tokens:
Colors:
teal: # New color palette for Light theme
'500': '#0694A2'
Styles:
Button:
backgroundColor: ${Colors.teal['500']} # Inherits primary from Common and overrides with teal
labelStyle:
color: white
Explanation:
Light
theme inherits styles and tokens from theCommon
theme.Light
theme overrides thebackgroundColor
of theButton
style with its ownteal
color.Light
theme'sButton
inherits theborderRadius
fromCommon
theme- Other styles from
Common
(like.topView
) are still applied to theLight
theme.
This example demonstrates how you can define a common base theme and then create specific themes like Light
and Dark
that inherit and modify styles as needed.
Properties
Now let us see what properties does it have on larger level
Property | Type | Description |
---|---|---|
material3 | boolean | If set true, material3 will be applied else material2. see here (opens in a new tab) for more details about Material Design 2 vs 3. |
Text | object | see properties |
Colors | object | see properties |
Widgets | object | see properties |
Transitions | object | see properties |
Text
Property | Type | Description |
---|---|---|
fontFamily | string | Allows users to chose a specific font-family other than the default one. see the list of all available font families here (opens in a new tab). |
displayLarge | object | Largest of display styles . As the largest text on the screen, display styles are reserved for short, important text or numerals. They work best on large screens. see properties |
displayMedium | object | Middle size of the display styles. As the largest text on the screen, display styles are reserved for short, important text or numerals. They work best on large screens. see properties |
displaySmall | object | Smallest of the display styles. As the largest text on the screen, display styles are reserved for short, important text or numerals. They work best on large screens. see properties |
headlineLarge | object | Largest of the headline styles. Headline styles are smaller than display styles. They're best-suited for short, high-emphasis text on smaller screens. see properties |
headlineMedium | object | Middle size of the headline styles. Headline styles are smaller than display styles. They're best-suited for short, high-emphasis text on smaller screens.see properties |
headlineSmall | object | Smallest of the headline styles. Headline styles are smaller than display styles. They're best-suited for short, high-emphasis text on smaller screens. see properties |
titleLarge | object | Largest of the title styles. Titles are smaller than headline styles and should be used for shorter, medium-emphasis text.see properties |
titleMedium | object | Middle size of the title styles. Titles are smaller than headline styles and should be used for shorter, medium-emphasis text. see properties |
titleSmall | object | Smallest of the title styles. Titles are smaller than headline styles and should be used for shorter, medium-emphasis text. see properties |
bodyLarge | object | Largest of the body styles. Body styles are used for longer passages of text. see properties |
bodyMedium | object | Middle size of the body styles. Body styles are used for longer passages of text. see properties |
bodySmall | object | Smallest of the body styles. Body styles are used for longer passages of text. see properties |
labelLarge | object | Largest of the label styles. Label styles are smaller, utilitarian styles, used for areas of the UI such as text inside of components or very small supporting text in the content body, like captions. see properties |
labelMedium | object | Middle size of the label styles. Label styles are smaller, utilitarian styles, used for areas of the UI such as text inside of components or very small supporting text in the content body, like captions. see properties |
labelSmall | object | Smallest of the label styles. Label styles are smaller, utilitarian styles, used for areas of the UI such as text inside of components or very small supporting text in the content body, like captions. see properties |
TextStyle
Property | Type | Description |
---|---|---|
fontSize | integer | Sets the size of the text. |
color | integer or string | The color specification for the text, which can be represented in different formats. It can be specified as a number, a predefined color name, or a hexadecimal value starting with '0x'. transparent black blue white red grey teal amber pink purple yellow green brown cyan indigo lime orange |
Colors
Property | Type | Description |
---|---|---|
seed | string or integer | Generate color schema based on seed color. The color specification for the text, which can be represented in different formats. It can be specified as a number, a predefined color name, or a hexadecimal value starting with '0x'. transparent black blue white red grey teal amber pink purple yellow green brown cyan indigo lime orange . more here |
primary | string or integer | Primary color of your App (e.g button color, focus color, ...). The color specification for the text, which can be represented in different formats. It can be specified as a number, a predefined color name, or a hexadecimal value starting with '0x'. transparent black blue white red grey teal amber pink purple yellow green brown cyan indigo lime orange |
onPrimary | string or integer | The color overlay on top of your primary color (e.g button text). The color specification for the text, which can be represented in different formats. It can be specified as a number, a predefined color name, or a hexadecimal value starting with '0x'. transparent black blue white red grey teal amber pink purple yellow green brown cyan indigo lime orange |
secondary | string or integer | The Secondary color of your App. The color specification for the text, which can be represented in different formats. It can be specified as a number, a predefined color name, or a hexadecimal value starting with '0x'. transparent black blue white red grey teal amber pink purple yellow green brown cyan indigo lime orange |
onSecondary | string or integer | The color overlay on top of your secondary color. The color specification for the text, which can be represented in different formats. It can be specified as a number, a predefined color name, or a hexadecimal value starting with '0x'. transparent black blue white red grey teal amber pink purple yellow green brown cyan indigo lime orange |
disabled | string or integer | Color when a widget is disabled. The color specification for the text, which can be represented in different formats. It can be specified as a number, a predefined color name, or a hexadecimal value starting with '0x'. transparent black blue white red grey teal amber pink purple yellow green brown cyan indigo lime orange |
loadingScreenBackgroundColor | string or integer | The background color while a screen is loading. The color specification for the text, which can be represented in different formats. It can be specified as a number, a predefined color name, or a hexadecimal value starting with '0x'. transparent black blue white red grey teal amber pink purple yellow green brown cyan indigo lime orange |
loadingScreenIndicatorColor | string or integer | The progress indicator color while a screen is loading. The color specification for the text, which can be represented in different formats. It can be specified as a number, a predefined color name, or a hexadecimal value starting with '0x'. transparent black blue white red grey teal amber pink purple yellow green brown cyan indigo lime orange |
Widgets
Property | Type | Description |
---|---|---|
Input | object | see properties |
Button | object | see properties |
Input
Property | Type | Description |
---|---|---|
variant | string | Select a pre-defined look and feel for Input widgets see properties |
fillColor | string or integer | The fill color for applicable input fields (TextInput, Dropdown, ...). which can be represented in different formats. It can be specified as a number, a predefined color name, or a hexadecimal value starting with '0x'. transparent black blue white red grey teal amber pink purple yellow green brown cyan indigo lime orange |
borderRadius | integer | The border radius for applicable Input widgets. |
borderWidth | integer | The border width for applicable Input widgets. |
borderColor | integer or string | The base border color for applicable input fields. This border color determines the look and feel of your inputs, while the other colors are overrides for different states, which can be represented in different formats. It can be specified as a number, a predefined color name, or a hexadecimal value starting with '0x'. transparent black blue white red grey teal amber pink purple yellow green brown cyan indigo lime orange |
disabledBorderColor | integer or string | The border color when input fields are disabled, which can be represented in different formats. It can be specified as a number, a predefined color name, or a hexadecimal value starting with '0x'. transparent black blue white red grey teal amber pink purple yellow green brown cyan indigo lime orange |
errorBorderColor | integer or string | The border color when there are errors on the input fields, which can be represented in different formats. It can be specified as a number, a predefined color name, or a hexadecimal value starting with '0x'. transparent black blue white red grey teal amber pink purple yellow green brown cyan indigo lime orange |
focusedBorderColor | integer or string | The border color of the input field when it is receiving focus |
focusedErrorBorderColor | integer or string | The border color of the input field when it is receiving focus in its error state, which can be represented in different formats. It can be specified as a number, a predefined color name, or a hexadecimal value starting with '0x'. transparent black blue white red grey teal amber pink purple yellow green brown cyan indigo lime orange |
hintStyle | object | see properties |
Button
Property | Type | Description |
---|---|---|
borderRadius | string or integer | The border radius of the widget.This can be specified using CSS-like notation with 1 to 4 integers. Minimum value: 0. |
borderColor | integer or string | Sets the border color, starting with '0xFF' for full opacity. transparent black blue white red grey teal amber pink purple yellow green brown cyan indigo lime orange |
borderWidth | integer | Thickness of the border. Minimum value should be 0. |
color | integer or string | The color specification for the text, icons, divider etc, which can be represented in different formats. It can be specified as a number, a predefined color name, or a hexadecimal value starting with '0x'. transparent black blue white red grey teal amber pink purple yellow green brown cyan indigo lime orange |
backgroundColor | integer or string | Background color of the box. which can be represented in different formats. It can be specified as a number, a predefined color name, or a hexadecimal value starting with '0x'. transparent black blue white red grey teal amber pink purple yellow green brown cyan indigo lime orange |
padding | string or integer | Padding with CSS-style value |
options for Input.variant
Property | Description |
---|---|
underline | Draw an Underline below applicable input widgets (default) |
box | Draw a Box border around applicable input widgets |
Transitions
Property | Type | Description |
---|---|---|
page | object | see properties |
modal | object | Same properties as the page property except alignment . |
Properties for Transitions.page
Property | Type | Description |
---|---|---|
type | string | Kind of transition types. Can read more about it here. Possible values are fade ,rightToLeft ,leftToRight ,topToBottom ,bottomToTop ,scale ,rotate ,size ,rightToLeftWithFade ,leftToRightWithFade ,leftToRightPop ,rightToLeftPop ,topToBottomPop ,bottomToTopPop |
alignment | string | The alignment of the widget relative to its parent. topLeft , topCenter , topRight , centerLeft , center , centerRight , bottomLeft , bottomCenter , bottomRight |
duration | integer | The duration in ms ( millisecond ) for which the transition animation happens. |