Skip to main content

Public API Reference

Myop components expose exactly two global functions on the window object. These functions form the communication contract between the component and its host application.

Overview​

FunctionDirectionPurpose
myop_init_interfaceHost → ComponentInitialize component with data
myop_cta_handlerComponent → HostSend user actions to host

myop_init_interface​

Purpose​

Initialize or update the component with data from the host application.

Signature​

window.myop_init_interface(data?: object): object | void

Usage Modes​

1. Initialization (with data)​

Pass data to initialize the component:

window.myop_init_interface({
components: [
{ id: "1", name: "Component A" },
{ id: "2", name: "Component B" }
]
});

2. Getter (without arguments)​

Call without arguments to get current state:

const currentState = window.myop_init_interface();
console.log(currentState);
// { components: [...] }

3. Action-Based Updates​

Support incremental updates with action types:

// Set all data
window.myop_init_interface({
action: 'setData',
payload: [/* components */]
});

// Add a single item
window.myop_init_interface({
action: 'addItem',
payload: { id: "3", name: "New Component" }
});

// Update an item
window.myop_init_interface({
action: 'updateItem',
payload: { id: "1", name: "Updated Name" }
});

// Remove an item
window.myop_init_interface({
action: 'removeItem',
payload: { id: "2" }
});

Implementation Example​

window.myop_init_interface = function(input) {
// Getter mode - return current state
if (!input) {
return {
components: allComponentsState,
filters: currentFilters,
selectedId: selectedItemId
};
}

// Action-based update
if (input.action) {
switch (input.action) {
case 'setData':
initializeComponent({ components: input.payload });
break;
case 'addItem':
addComponent(input.payload);
break;
case 'updateItem':
updateComponent(input.payload);
break;
case 'removeItem':
removeComponent(input.payload.id);
break;
case 'setFilter':
setFilter(input.payload);
break;
case 'clearFilters':
clearAllFilters();
break;
default:
console.warn('Unknown action:', input.action);
}
return;
}

// Direct data initialization
initializeComponent(input);
};

Data Contract​

Define a clear data contract between host and component:

// TypeScript interface for documentation
interface ComponentData {
components: Array<{
id: string;
name: string;
description?: string;
developerName: string;
lastEditedDate: string; // ISO 8601 format
lastVersionName: string;
environments: string[];
tags: string[];
}>;
}

interface ActionPayload {
action: 'setData' | 'addItem' | 'updateItem' | 'removeItem';
payload: any;
}

type InitInput = ComponentData | ActionPayload;

myop_cta_handler​

Purpose​

Handle user actions and communicate events back to the host application. "CTA" stands for "Call to Action".

Signature​

window.myop_cta_handler(action_id: string, payload?: object): void

Parameters​

ParameterTypeDescription
action_idstringIdentifier for the action type
payloadobjectOptional data associated with the action

Common Action Types​

// Navigation actions
window.myop_cta_handler('navigate', { path: '/components/123' });
window.myop_cta_handler('component_clicked', { componentId: 'comp-123' });
window.myop_cta_handler('back', {});

// Modal/Dialog actions
window.myop_cta_handler('open_modal', { type: 'edit', itemId: '123' });
window.myop_cta_handler('close_modal', {});
window.myop_cta_handler('confirm_delete', { itemId: '123' });

// Data actions
window.myop_cta_handler('save', { data: formData });
window.myop_cta_handler('delete', { itemId: '123' });
window.myop_cta_handler('refresh', {});

// UI state actions
window.myop_cta_handler('select', { itemId: '123' });
window.myop_cta_handler('toggle_expand', { sectionId: 'details' });
window.myop_cta_handler('filter_change', { filters: activeFilters });

// Error/status actions
window.myop_cta_handler('error', { message: 'Something went wrong' });
window.myop_cta_handler('retry', {});

Implementation in Component​

The component defines a default handler that logs actions:

// Default handler (logs to console)
window.myop_cta_handler = function(action_id, payload) {
console.log('CTA Handler:', action_id, payload);
};

Implementation in Host​

The host application overrides the handler to respond to actions:

// React host example
component.props.myop_cta_handler = (action_id, payload) => {
switch (action_id) {
case 'component_clicked':
navigate(`/components/${payload.componentId}`);
break;
case 'delete':
confirmAndDelete(payload.itemId);
break;
case 'filter_change':
updateUrlParams(payload.filters);
break;
case 'error':
showToast(payload.message, 'error');
break;
}
};

Best Practices for Action IDs​

PatternExampleDescription
noun_verbcomponent_clickedEntity + past tense action
verbnavigate, save, deleteSimple action verbs
verb_nounopen_modal, close_dialogAction + target

Communication Patterns​

One-Way: Host → Component​

Host                          Component
│ │
│ myop_init_interface(data) │
│ ─────────────────────────────>│
│ │ Process data
│ │ Render UI
│ │

One-Way: Component → Host​

Host                          Component
│ │
│ │ User clicks button
│ myop_cta_handler(action) │
│<───────────────────────────── │
│ Handle action │
│ │

Round-Trip: Request/Response​

Host                          Component
│ │
│ myop_init_interface(data) │
│ ─────────────────────────────>│
│ │ Process data
│ │ User interacts
│ myop_cta_handler(action) │
│<───────────────────────────── │
│ Handle action │
│ Fetch new data │
│ │
│ myop_init_interface(newData) │
│ ─────────────────────────────>│
│ │ Update UI

Complete Example​

Component Implementation​

(function() {
let components = [];
let selectedId = null;

function render() {
const list = document.getElementById('list');
list.innerHTML = components.map(comp => `
<div class="item ${comp.id === selectedId ? 'selected' : ''}"
data-id="${comp.id}">
${comp.name}
</div>
`).join('');
}

document.getElementById('list').addEventListener('click', (e) => {
const item = e.target.closest('.item');
if (item) {
selectedId = item.dataset.id;
render();
window.myop_cta_handler('component_clicked', {
componentId: selectedId
});
}
});

document.getElementById('delete-btn').addEventListener('click', () => {
if (selectedId) {
window.myop_cta_handler('delete', { itemId: selectedId });
}
});

// Public API
window.myop_init_interface = function(data) {
if (!data) {
return { components, selectedId };
}

if (data.action === 'removeItem') {
components = components.filter(c => c.id !== data.payload.id);
if (selectedId === data.payload.id) selectedId = null;
render();
return;
}

components = data.components || [];
render();
document.getElementById('loader').style.display = 'none';
};

window.myop_cta_handler = function(action_id, payload) {
console.log('Action:', action_id, payload);
};
})();

Host Implementation​

import { MyopContainer } from "@myop/react";

function ComponentList() {
const navigate = useNavigate();
const [components, setComponents] = useState([]);

useEffect(() => {
fetchComponents().then(setComponents);
}, []);

return (
<MyopContainer
componentId="abc-123"
onReady={(component) => {
// Set up action handler
component.props.myop_cta_handler = (action, payload) => {
switch (action) {
case 'component_clicked':
navigate(`/component/${payload.componentId}`);
break;
case 'delete':
deleteComponent(payload.itemId).then(() => {
component.props.myop_init_interface({
action: 'removeItem',
payload: { id: payload.itemId }
});
});
break;
}
};

// Initialize with data
component.props.myop_init_interface({ components });
}}
/>
);
}

Next Steps​