Appearance
UI Element
Overview
UI Elements are the foundational building blocks for creating custom user interface components in the Stripo Email Editor. They enable you to extend the editor's interface with custom inputs, pickers, dropdowns, and specialized interactive components that go beyond standard HTML form elements. UI Elements can be embedded within controls and settings panels to provide rich, interactive functionality tailored to your specific needs.
Purpose and Core Concepts
What is a UI Element?
A UI Element in the Stripo Extensions SDK is a reusable UI component that:
- Defines custom interactive interface elements (color pickers, dropdowns, custom inputs, etc.)
- Can be embedded within controls
- Maintains state and responds to external attribute changes
- Integrates seamlessly with the editor's control system
- Provides lifecycle hooks for initialization and cleanup
- Communicates value changes to parent controls
Built-in vs Custom UI Elements
The SDK provides a rich set of built-in UI elements for common use cases, but you can also create custom UI elements when you need specialized functionality:
Built-in UI Elements - Ready to use without additional configuration:
- Buttons, checkboxes, radio buttons
- Text inputs, textareas, date pickers
- Color pickers, font family selectors
- Dropdown selects, switchers, counters
- Labels, messages, icons
- And more (see the Built-in UI Elements table)
Custom UI Elements - When built-in elements don't meet your needs:
- Brand-specific color palette pickers
- Advanced file uploaders with preview
- Custom merge tag selectors
- Specialized input validators
- Integration with external services
- Complex multi-field components
Creating Custom UI Elements
To create a custom UI element, follow these steps:
- Create a class that extends the
UIElement
class - Register your UI element with the
ExtensionBuilder
UI element configuration requires:
- Unique element identifier (
getId()
)- This identifier is used as a tag name in control templates
- It must be unique across all UI elements in the extension
- HTML template structure (
getTemplate()
) - Render logic (
onRender()
)- Register all event listeners and other UI element-specific logic here
- Cleanup logic (
onDestroy()
)- Remove all event listeners and other UI element-specific logic here
- Getter and setter methods to maintain UI element state from parent control
- (Optional) Attribute update handler (
onAttributeUpdated()
)- This method is called when an attribute of the UI element is updated from the parent control
Once registered, you can use your custom UI element in control templates by referencing its ID:
javascript
import {UIElement, ExtensionBuilder} from '@stripoinc/ui-editor-extensions';
class BrandColorPickerUIElement extends UIElement {
getId() {
return 'brand-color-picker';
}
getTemplate() {
return `
<div class="brand-color-picker-palette" style="display: flex; gap: 16px;">
<button
data-value="#ff6f61"
style="width: 30px; height: 30px; border-radius: 50%; border: none; background-color: #ff6f61; cursor: pointer;"
title="Coral"></button>
<button
data-value="#43e97b"
style="width: 30px; height: 30px; border-radius: 50%; border: none; background-color: #43e97b; cursor: pointer;"
title="Mint"></button>
<button
data-value="#5f72bd"
style="width: 30px; height: 30px; border-radius: 50%; border: none; background-color: #5f72bd; cursor: pointer;"
title="Violet"></button>
</div>
`;
}
onRender(container) {
this.palette = container.querySelector('.brand-color-picker-palette');
this.palette.addEventListener('click', this.paletteClickHandler.bind(this));
}
onDestroy() {
this.palette.removeEventListener('click', this.paletteClickHandler.bind(this));
}
paletteClickHandler(e) {
const selectedColor = e.target.getAttribute('data-value');
// Trigger value change to parent control.
// The 'setValue' method will be called automatically.
this.api.triggerValueChange(selectedColor);
}
getValue() {
return this.palette.querySelector('button.selected')?.getAttribute('data-value');
}
setValue(_value) {
this.palette.querySelector('button.selected')?.classList.remove('selected');
this.palette.querySelector(`button[data-value="${_value}"]`)?.classList.add('selected');
}
onAttributeUpdated(_name, _value) {
// Handle attribute updates from parent control
console.log(`Attribute updated: ${_name} = `, _value);
}
}
class BrandControl extends Control {
getId() {
return 'brand-control';
}
getTemplate() {
return `<brand-color-picker name="brandColorPicker"></brand-color-picker>`;
}
onRender() {
this.api.onValueChanged('brandColorPicker', (newValue, oldValue) => {
// Handle value changes from 'brandColorPicker' UI element
console.log('brandColorPicker value changed:', newValue);
});
}
onTemplateNodeUpdated(node) {
// Update UI to reflect template state
this.api.updateValues({
'brandColorPicker': '#43e97b' // Get actual value from node
});
// Optionally, set UI element state with attribute values
this.api.setUIEAttribute('brandColorPicker', 'preferred-color', '#53f97a');
}
}
export default new ExtensionBuilder()
.addUiElement(BrandColorPickerUIElement)
.addControl(BrandControl)
.build();
Built-in UI Elements
Supported Built-in UI Elements
The following image and table list all built-in UI elements available in the Stripo Extensions SDK:
Tag Name | Alias | Description | Common Attributes |
---|---|---|---|
<ue-button> | UIElementType.BUTTON | Button element for triggering actions | name , disabled , caption , icon |
<ue-check-buttons> | UIElementType.CHECK_BUTTONS | Group of checkboxes as buttons | name , disabled , buttons |
<ue-checkbox> | UIElementType.CHECKBOX | Checkbox input for boolean values | name , disabled , caption |
<ue-color> | UIElementType.COLOR | Color picker for selecting colors | name , disabled |
<ue-counter> | UIElementType.COUNTER | Numeric input with increment/decrement buttons | name , disabled , min-value , max-value , step |
<ue-datepicker> | UIElementType.DATEPICKER | Date picker for selecting dates | name , disabled , placeholder , min-date |
<ue-expandable> | UIElementType.EXPANDABLE | Expandable/collapsible container | name , expanded |
<ue-icon> | UIElementType.ICON | Icon display element | name , img , src , title , width , height , image-class , hint , is-active , visibility , transform |
<ue-label> | UIElementType.LABEL | Text label with optional hint | name , text , hint |
<ue-message> | UIElementType.MESSAGE | Message box for displaying information | name , type |
<ue-radio-buttons> | UIElementType.RADIO_BUTTONS | Radio button group | name , disabled , buttons |
<ue-select> | UIElementType.SELECTPICKER | Dropdown select picker | name , disabled , searchable , multi-select , placeholder , items |
<ue-switcher> | UIElementType.SWITCHER | Toggle switcher for boolean values | name , disabled |
<ue-text> | UIElementType.TEXT | Single-line text input | name , disabled , placeholder |
<ue-textarea> | UIElementType.TEXTAREA | Multi-line text input | name , disabled , resizable , placeholder |
Using Built-in UI Elements
All built-in UI elements can be used directly in your control templates without additional registration by referencing their tag names or aliases:
Simple Usage
javascript
class ComprehensiveControl extends Control {
getId() {
return 'comprehensive-control';
}
getTemplate() {
return `
<div class="container two-columns">
<${UIElementType.LABEL} ${UEAttr.LABEL.text}="<ue-button>"></${UIElementType.LABEL}>
<${UIElementType.COLOR} ${UEAttr.COLOR.name}="colorPicker"></${UIElementType.COLOR}>
</div>`;
}
onRender() {
// Listen for 'colorPicker' UI element value changes
this.api.onValueChanged('colorPicker', (newValue, oldValue) => {
this.api.getDocumentModifier()
.modifyHtml(this.node.querySelector(`.custom-message-area`))
.setStyle('background-color', newValue)
.apply(new ModificationDescription(`Updated background color to ${newValue}`));
})
}
onTemplateNodeUpdated(node) {
this.node = node;
// Set the value for 'colorPicker' UI element
const element = node.querySelector('.custom-message-area');
this.api.updateValues({
'colorPicker': node.querySelector(`.custom-message-area`).getStyle('background-color')
});
}
}
Complex Usage
Expandable container
Expandable containers allow you to group multiple UI elements inside a collapsible section, making complex forms more organized and user-friendly. An expandable UI element is composed of three main parts:
<ue-expandable>
— The main wrapper for the entire collapsible section<ue-expandable-header>
— The header area, typically containing the title, placed next to the expand/collapse toggle<ue-expandable-content>
— The container for the content that is shown or hidden when expanded or collapsed
javascript
class ExpandableControl extends Control {
getTemplate() {
return `
<div class="container">
<${UIElementType.EXPANDABLE}>
<${UIElementType.EXPANDABLE_HEADER}>
<${UIElementType.LABEL} ${UEAttr.LABEL.text}="Click to expand"></${UIElementType.LABEL}>
</${UIElementType.EXPANDABLE_HEADER}>
<${UIElementType.EXPANDABLE_CONTENT}>
<${UIElementType.LABEL} ${UEAttr.LABEL.text}="First content row"></${UIElementType.LABEL}>
<${UIElementType.LABEL} ${UEAttr.LABEL.text}="Another row"></${UIElementType.LABEL}>
</${UIElementType.EXPANDABLE_CONTENT}>
</${UIElementType.EXPANDABLE}>
</div>`;
}
// Additional configuration should be here
}
Overriding Built-in UI Elements
The UIElementTagRegistry allows you to replace built-in UI elements with custom implementations throughout your extension. This is particularly useful when you want to:
- Apply consistent branding to all UI elements
- Add custom functionality to standard elements
- Integrate with external services
- Enforce specific validation or formatting rules
Creating a Tag Registry
To override built-in UI elements:
- Create a class that extends
UIElementTagRegistry
- Implement the
registerUiElements()
method - Map tags to your custom UI element IDs
- Register the registry with
ExtensionBuilder
javascript
import {UIElementTagRegistry, UIElementType, ExtensionBuilder} from '@stripoinc/ui-editor-extensions';
class CustomTagRegistry extends UIElementTagRegistry {
registerUiElements(uiElementsTagsMap) {
// Override the built-in color picker with custom implementation
uiElementsTagsMap[UIElementType.COLOR] = 'brand-color-picker';
}
}
export default new ExtensionBuilder()
.addUiElement(BrandColorPickerUIElement)
.withUiElementTagRegistry(CustomTagRegistry)
.build();
UI Element API
The UI Element API, accessible through this.api
, provides method to notify the parent control when the UI element's value changes, ensuring proper synchronization and state management.
For complete API reference, see UIElementApi.