---
sidebar_position: 4
---
# 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

| Function | Direction | Purpose |
|----------|-----------|---------|
| `myop_init_interface` | Host → Component | Initialize component with data |
| `myop_cta_handler` | Component → Host | Send user actions to host |

## myop_init_interface

### Purpose

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

### Signature

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

### Usage Modes

#### 1. Initialization (with data)

Pass data to initialize the component:

```javascript
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:

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

#### 3. Action-Based Updates

Support incremental updates with action types:

```javascript
// 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

```javascript
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
// 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

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

### Parameters

| Parameter | Type | Description |
|-----------|------|-------------|
| `action_id` | `string` | Identifier for the action type |
| `payload` | `object` | Optional data associated with the action |

### Common Action Types

```javascript
// 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:

```javascript
// 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:

```javascript
// 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

| Pattern | Example | Description |
|---------|---------|-------------|
| `noun_verb` | `component_clicked` | Entity + past tense action |
| `verb` | `navigate`, `save`, `delete` | Simple action verbs |
| `verb_noun` | `open_modal`, `close_dialog` | Action + 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

```javascript
(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

```jsx
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

- See [Host Integration](/docs/learnMyop/html-components/host-integration) for framework-specific examples
- Review [Best Practices](/docs/learnMyop/html-components/best-practices) for component development
