Appearance
BaseApi
Core interface providing fundamental API functionality for all extension components in the Stripo Email Editor Extensions SDK.
typescript
interface BaseApi
Description
The BaseApi
interface defines the fundamental API methods available to all extension components, including blocks, controls, renderers, and context actions. It provides access to editor configuration, internationalization, state management, and UI features such as popovers.
Import
typescript
import { BaseApi } from '@stripoinc/ui-editor-extensions';
Properties
None (all functionality is provided through methods)
Methods
getDocumentRootHtmlNode()
Retrieves the root immutable HTML node of the document template.
typescript
getDocumentRootHtmlNode(): ImmutableHtmlNode
Returns
ImmutableHtmlNode
- The root HTML node of the email document
Usage Notes
- Provides read-only access to the entire document structure
- Use for querying elements across the document
- Combine with selectors to find specific nodes
- Immutable nodes ensure document consistency
Example
typescript
const rootNode = this.api.getDocumentRootHtmlNode();
const allImages = rootNode.querySelectorAll('img');
const stripeCount = rootNode.querySelectorAll('.esd-stripe').length;
getDocumentRootCssNode()
Retrieves the root immutable CSS node of the document's stylesheet.
typescript
getDocumentRootCssNode(): ImmutableCssNode
Returns
ImmutableCssNode
- The root CSS node containing all styles
Usage Notes
- Provides access to document-level CSS rules
- Allows querying for specific CSS rules or media queries
- Enables reading CSS properties and values
- Essential for style-related controls
Example
typescript
const desktopH1CssNode = this.api.getDocumentRootCssNode().querySelector('h1');
const mobileH1CssNode = this.api.getDocumentRootCssNode().querySelector('@{media only screen and (max-width: 600px)} h1');
getEditorConfig()
Retrieves the current configuration settings of the editor instance.
typescript
getEditorConfig(): Record<string, unknown>
Returns
Record<string, unknown>
- A record object containing editor configuration key-value pairs
Usage Notes
- Contains editor features, metadata, and settings
- Configuration is set during editor initialization
- May include custom metadata for your application
- Read-only—configuration cannot be modified through this method
Example
typescript
const config = this.api.getEditorConfig();
// Access standard configuration
const locale = config.locale;
const name = config.name;
const emailId = config.metadata.emailId;
// Access custom data
const enabled = config.customBlock?.enabled;
translate()
Translates a given key into the currently configured language, optionally interpolating parameters.
typescript
translate(key: string, params?: Record<string, unknown>): string
Parameters
Parameter | Type | Description |
---|---|---|
key | string | The localization key to translate |
params | Record<string, unknown> | Optional parameters for interpolation into the translated string |
Returns
string
- The translated string
Usage Notes
- Respects the current editor language setting
- Supports parameter interpolation using placeholders
- Returns the key itself if translation is not found
- Essential for creating multilingual extensions
Example
typescript
// Simple translation
const title = this.api.translate('block.product.title');
// Translation with parameters
const message = this.api.translate('block.product.count', {
count: 5,
total: 10
});
// If translation is "Showing {count} of {total} products"
// Result: "Showing 5 of 10 products"
// Using in block names
public getName(): string {
return this.api.translate('blocks.myBlock.name');
}
addCustomFont()
Adds a new font family to the editor configuration.
typescript
addCustomFont(font: CustomFontFamily): void
Parameters
Parameter | Type | Description |
---|---|---|
font | CustomFontFamily | Font family configuration object |
Usage Notes
- Makes font available in all font selection dropdowns
- Font CSS is automatically loaded if URL is provided
- Useful for brand-specific or custom fonts
- Fonts are available for the entire editor session
Example
typescript
// Add a custom brand font
this.api.addCustomFont({
name: 'Brand Font',
fontFamily: 'BrandFont, Arial, sans-serif',
url: 'https://fonts.example.com/brand-font.css'
});
ignoreClickOutside()
Controls whether clicking outside the current element triggers deselection.
typescript
ignoreClickOutside(ignore: boolean): void
Parameters
Parameter | Type | Description |
---|---|---|
ignore | boolean | If true, disables deselection on outside clicks; if false, enables it |
Usage Notes
- Useful when showing custom UI that users need to interact with
- Prevents loss of context when using external controls
- Remember to reset (set to false) when interaction is complete
- Only affects the current selection context
Example
typescript
public onSelect(node: ImmutableHtmlNode): void {
// Prevent deselection while configuration dialog is open
this.api.ignoreClickOutside(true);
this.showConfigurationDialog({
onClose: () => {
// Re-enable normal deselection behavior
this.api.ignoreClickOutside(false);
}
});
}
// Another example with external panel
private openExternalPanel(): void {
this.api.ignoreClickOutside(true);
const panel = document.getElementById('external-panel');
panel.style.display = 'block';
panel.addEventListener('close', () => {
this.api.ignoreClickOutside(false);
}, { once: true });
}
getEditorState()
Returns information about the active state of the editor.
typescript
getEditorState(): {
previewDeviceMode: PreviewDeviceMode;
panelPosition: PanelPosition;
}
Returns
Object containing:
Property | Type | Description |
---|---|---|
previewDeviceMode | PreviewDeviceMode | Current preview mode |
panelPosition | PanelPosition | Position of the settings panel |
Usage Notes
- Use to adapt behavior based on preview mode
- State reflects current user interface configuration
- Useful for responsive behavior in extensions
Example
typescript
const state = this.api.getEditorState();
// Adapt to preview mode
if (state.previewDeviceMode === PreviewDeviceMode.MOBILE) {
// Simplified behavior for mobile preview
this.useMobileSettings();
} else {
// Full desktop functionality
this.useDesktopSettings();
}
// Check panel position
if (state.panelPosition === PanelPosition.BLOCKS_SETTINGS) {
// Adjust UI accordingly
}
onEditorStatePropUpdated()
Subscribes to changes in specific editor state properties.
typescript
onEditorStatePropUpdated(
prop: EditorStatePropertyType,
callback: (newValue: unknown, oldValue: unknown) => void
): void
Parameters
Parameter | Type | Description |
---|---|---|
prop | EditorStatePropertyType | The property to monitor for changes |
callback | Function | Function called when the property value changes |
EditorStatePropertyType
See EditorStatePropertyType
for available property types.
Usage Notes
- Callback is triggered whenever the specified property changes
- Useful for reactive UI updates
- Multiple subscriptions to the same property are supported
- No automatic cleanup - subscriptions persist for component lifetime
Example
typescript
public onDocumentInit(): void {
// Monitor preview mode changes
this.api.onEditorStatePropUpdated(
EditorStatePropertyType.previewDeviceMode,
(newMode, oldMode) => {
console.log(`Preview changed from ${oldMode} to ${newMode}`);
this.updateBlockDisplay(newMode);
}
);
}
private updateBlockDisplay(mode: PreviewDeviceMode): void {
if (mode === PreviewDeviceMode.MOBILE) {
// Update for mobile preview
}
}
openAIPopover()
Opens an AI assistant popover anchored to a target element.
typescript
openAIPopover(options: AIPopoverOptions): void
Parameters
Parameter | Type | Description |
---|---|---|
options | AIPopoverOptions | Configuration for the AI popover |
Usage Notes
- Requires AI features to be enabled in editor configuration
- Provides context-aware content generation
- Popover placement auto-adjusts to stay visible
- User must have appropriate permissions for AI features
Example
typescript
import {ExtensionPopoverType, PopoverSide, UIElement} from '@stripoinc/ui-editor-extensions';
export class AIPopoverUIElement extends UIElement {
getId() {
return 'ai-popover-element';
}
getTemplate() {
return `
<div>
<button class="ai-button">Improve with AI</button>
</div>`
}
onRender(container) {
this.aiButton = container.querySelector('.ai-button');
this.aiButton.addEventListener('click', this.showAiPopover.bind(this));
}
showAiPopover() {
this.api.openAIPopover({
targetElement: this.aiButton,
value: 'Hello world',
preferredSides: [PopoverSide.LEFT],
type: ExtensionPopoverType.AI_TEXT,
onResult: (result) => {console.log(result)}
})
}
onDestroy() {
this.aiButton.removeEventListener('click', this.showAiPopover.bind(this));
}
}
openEmojiPopover()
Opens an emoji picker popover anchored to a target element.
typescript
openEmojiPopover(options: EmojiPopoverOptions): void
Parameters
Parameter | Type | Description |
---|---|---|
options | EmojiPopoverOptions | Configuration for the emoji picker |
Usage Notes
- Shows native emoji picker interface
- Supports search and categories
- Auto-positions to stay within viewport
- Returns the selected emoji character
Example
typescript
import {ExtensionPopoverType, PopoverSide, UIElement} from '@stripoinc/ui-editor-extensions';
export class EmojiPopoverUIElement extends UIElement {
getId() {
return 'emoji-popover-element';
}
getTemplate() {
return `
<div>
<button class="emoji-button">Pick Emoji</button>
</div>`
}
onRender(container) {
this.emojiButton = container.querySelector('.emoji-button');
this.emojiButton.addEventListener('click', this.showEmojiPopover.bind(this));
}
showEmojiPopover() {
this.api.openEmojiPopover({
targetElement: this.emojiButton,
preferredSides: [PopoverSide.LEFT],
onResult: (result) => {console.log(result)}
})
}
onDestroy() {
this.emojiButton.removeEventListener('click', this.showEmojiPopover.bind(this));
}
}
Implementation Context
The BaseApi
is available in various extension components through their respective API properties:
- Block: Access via
this.api
in block methods - Control: Access via
this.api
in control methods - BlockRenderer: Access via
this.api
in renderer methods - ContextAction: Access via
this.api
in action methods
Best Practices
- Always use translations for user-facing text to support internationalization
- Check configuration before using optional features
- Reset interaction states (like
ignoreClickOutside
) when done - Subscribe to state changes early in component lifecycle
- Validate configuration values before using them