Preview Appearance APIs
Introduction
This guide explains the APIs offered by Mendix Studio Pro so you can build better pluggable widgets. Specifically, you can use these APIs and modules to alter pluggable widgets' preview appearances while working in Studio Pro's Design mode.
In contrast, Client APIs Available to Pluggable Widgets is meant for pluggable widget development once your app is running in the client. This guide's APIs are available in Mendix 8.0.0 and higher.
Values API
The values API passes the values configured for a pluggable widget's properties. These values will be passed in a JavaScript object, where the property's key is used as the object property.
Here is an example of such an object:
{
stringProp: "Some value",
intProp: 42
}Static Properties
Static property types are exposed with their configured value as a JavaScript value:
| Plugin Widget Type | JavaScript Type |
|---|---|
string |
string |
boolean |
boolean |
integer |
number |
decimal |
number |
enumeration |
string |
For enumeration properties, the currently selected option's key will be used as the value.
Icon
This property appears as follows:
type GlyphIcon = { type: "glyph"; iconClass: string; }
type ImageIcon = { type: "image"; imageUrl: string; }
type IconProperty = null | GlyphIcon | ImageIcon;Icon properties are exposed objects containing a type field that is "glyph" if a glyphicon is selected, "image" if an image is selected, or null if no icon is selected at all.
For the "glyph" type, iconClass is available. It contains the class to apply on a glyphicon element to display the correct icon. It will be an empty string value if no icon has been selected.
For the "image" type, imageUrl is available. It represents a URL from which your selected image can be reached by Studio Pro's Design mode. It will be an empty string value if no image has been selected.
Image
This property appears as follows:
type StaticImage = { type: "static"; imageUrl: string; };
type DynamicImage = { type: "dynamic"; entity: string; };
type ImageProperty = null | StaticImage | DynamicImage;Image properties are exposed objects containing a type field that is "static" if a static image is selected, "dynamic" if an entity is selected, or null if no image is selected at all.
For the "static" type, imageUrl is available. It represents a URL from which your selected image can be reached by Studio Pro's Design mode. It will be an empty string value if no image has been selected.
For the "dynamic" type, entity is available. It represents the entity where the selected image's data is stored. It will be an empty string value if no entity has been selected.
Widgets
This property appears as follows:
type WidgetsProperty = {
widgetCount: number;
renderer: React.Component
}This property is exposed as an object containing the following properties:
widgetCount: The number of immediate child widgets configuredrenderer: A React component allowing rendering of the child widgets in the preview
Expression
This property will be passed as a string value containing the expression as typed by the user.
Text Template
A preview string will be passed. This preview is built using the currently active language, and by replacing the placeholders with the names of the attributes.
For example, you could see these placeholders:
Name: {1}
Description: {2}Using parameters EventName and EventDescription instead of the placeholders would look like this:
Name: {EventName}
Description: {EventDescription}Action
When an action is set, an empty object {} is passed to indicate that an action has been set. When no client action is set, the passed value will be null.
Attribute
A string containing the path of the selected attribute will be passed.
Here are a few examples:
EventNameMyFirstModule.EventSchedule_Event/MyFirstModule.Event/EventName
Object
Object properties are passed as an array of JavaScript objects. For each configured sub-object, an object will be passed with all the sub-object's properties. These properties are available by their key, with values as described throughout the Values API section.
File
A string containing the path of the selected file entity will be passed.
Here are a few examples:
MyFirstModule.EventMyFirstModule.EventSchedule_Event/MyFirstModule.Event
Preview Module for Studio Pro's Design Mode
It is possible to create a preview for pluggable widgets in Studio Pro's Design Mode.
Add the module by adding a file to your custom widget with the same name as your xml file as well as the suffix
.editorPreview.js. For example, a widget named TextBox.xml would have the preview module TextBox.editorPreview.js.
This preview module is expected to be a CommonJS module, exporting the following functions using the exports object.
Exposed Libraries
In Design mode, only a few libraries are allowed to be imported. This is expected to occur through the CommonJS method: by using require.
It is possible to require the following modules:
- The react libraries
"react","react-dom","react-dom-factories", and"prop-types" - An
Iconcomponent that can be used to render icon properties:"mendix/components/web/Icon" - A
Selectablecomponent that can be used to define what it selectable in preview:"mendix/preview/Selectable"
Preview Export
The preview export is expected to be a class or function representing a React component. This component, the values object (see the Values API section above), and the following properties will be rendered along with the values as properties:
readOnly(boolean):trueif the widget is read-only (for example, if it is configured to be so due to theEditabilitysystem property, or if it is inside a read-only data view)className(string): the classes from the system, which will include manually configured classes through theclassproperty in Studio Pro, and the classes resulting from configured design propertiesstyle(string): a string representation of the styles as entered in thestyleproperty in Studio Pro
Assuming a pluggable widget with the string properties content and style, the following shows a simple preview component:
type Props = {
content: string;
style: string;
className: string;
}
export const preview: React.FC<Props> = (props) => (
<div className={`my-pw-container ${props.className}`} style={props.style}>
{props.content}
</div>
);Using a Widgets Property
A Widgets Property contains a renderer field that allows its content to be rendered when filled, or shows an empty drop-zone when empty inside the preview. It requires a single, empty, DOM node as a child in which to render the contents:
type Props = {
content: WidgetsProperty;
}
export const preview: React.FC<Props> = (props) => {
const ContentRenderer = props.content.renderer;
return (
<div className="my-pw-container">
<div className="my-pw-header">…</div>
<ContentRenderer><div className="my-pw-content" /></ContentRenderer>
</div>
);
}Using an Icon Property
The preview module provides a component to preview an icon property in the same way as the
Icon component in the client would. This component can be imported from "mendix/components/web/Icon" and accepts
the IconProperty as icon parameter.
import { Icon } from "mendix/components/web/Icon";
type Props = {
icon: IconProperty;
}
export const preview: React.FC<Props> = (props) => (
<div className="my-pw-container">
<Icon icon={props.icon} />
<div className="my-pw-content">…</div>
</div>
);Using the Selectable Component
The preview module provides a component to define that an object is selectable in the preview. This component can be imported from "mendix/preview/Selectable", accepts an item from an object list property as an object parameter, and has an optional caption parameter.
The example below defines a simplified representation of the types for your clarity. In reality you would import those types from "../typings/TruckWidgetProps" if TruckWidget was the name of your widget.
import { Selectable } from "mendix/preview/Selectable";
type TruckDriversType = {
name: string;
age: number;
isExperienced: boolean;
}
type TruckWidgetPreviewProps = {
truckDrivers: TruckDriversType[];
}
export const preview: React.FC<TruckWidgetPreviewProps> = (props) => (
<div className="my-pw-container">
{props.truckDrivers.map((truckDriver, i) => (
<Selectable
object={truckDriver}
caption={truckDriver.isExperienced ? "Awesome truck driver" : undefined}
key={`truck_driver_${i}`}
>
<div className="my-pw-truck-driver">
<div>Name: {truckDriver.name}</div>
<div>Age: {truckDriver.age}</div>
</div>
</Selectable>
))}
</div>
)When the widget is added to a page you can select a specific item and edit it:
The GetPreviewCss Export
The getPreviewCss export is expected to be a function returning a string containing any CSS that the preview needs
to render.
export function getPreviewCss() {
return `
.my-pw-container {
background-color: #C0FFEE;
}
`;
}Read More
- Client APIs Available to Pluggable Widgets (Mendix 8)
- Pluggable Widget Property Types (Mendix 8)
- How to Build a Pluggable Native Widget