Skip to main content

Mapplets

Mapplets are the core building blocks of Mapples applications. They are self-contained components that integrate with the Mapples ecosystem to provide interactive, data-driven experiences. This guide shows you how to create and use Mapplets effectively.

What is a Mapplet?

A Mapplet is a React component that leverages Mapples packages to create rich, interactive interfaces. It combines:

  • @mapples/render - For rendering UI components
  • @mapples/types - For TypeScript type definitions
  • @mapples/action - For handling user interactions
  • @mapples/state - For managing application state

Auto-Generated Mapplet Example

When you run Mapples CLI commands, they automatically generate Mapplet components for you. You can generate Mapplets using any of the following commands:

npx @mapples/cli init
npx @mapples/cli sync
npx @mapples/cli pages --sync

Here's an example of what an auto-generated Mapplet looks like after running these commands:

import { RenderComponent } from '@mapples/render';
import { MappletType } from '@mapples/types';
import ActionProvider from '@mapples/action';
import StateProvider from '@mapples/state';

import { root } from './Home.json';

// @todo: This Mapplet can be updated
// read docs of how you can customize it: https://docs.com
export type HomeMappletProps<T extends object> = MappletType<T> & {};

export default function HomeMapplet<State extends object = object>({
state,
onAction,
}: HomeMappletProps<State>) {
return (
<StateProvider state={state}>
<ActionProvider onAction={onAction}>
<RenderComponent {...root} />
</ActionProvider>
</StateProvider>
);
}

Key Components Explained

  • StateProvider: Provides state management context to child components
  • ActionProvider: Handles user interactions and action dispatching
  • RenderComponent: Renders the UI based on the JSON configuration from Mapples Creator
  • MappletType: TypeScript interface that ensures type safety for your Mapplet props

Using Mapplets in Expo Router

Once you have created a Mapplet, you can use it in your Expo application. Here's how to integrate it at the top level using Expo Router:

In your app/index.tsx:

import React from 'react';
import { View, StyleSheet } from 'react-native';
import HomeMapplet from '../components/HomeMapplet';

// Define your application state
const appState = {
user: {
name: 'John Doe',
email: 'john@example.com',
preferences: {
theme: 'light',
language: 'en'
}
},
navigation: {
currentScreen: 'home',
history: []
},
content: {
title: 'Welcome to Mapples',
description: 'Build amazing apps with ease'
}
};

export default function HomeScreen() {
// Handle actions from the Mapplet
const handleMappletAction = (action: any) => {
console.log('Action received:', action);

// Handle different action types
switch (action.type) {
case 'NAVIGATE':
// Handle navigation
console.log('Navigate to:', action.payload.screen);
break;
case 'UPDATE_USER':
// Handle user updates
console.log('Update user:', action.payload);
break;
default:
console.log('Unknown action:', action);
}
};

return (
<View style={styles.container}>
<HomeMapplet
state={appState}
onAction={handleMappletAction}
/>
</View>
);
}

const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
},
});

Advanced Usage with Dynamic State

For more complex applications, you might want to manage state dynamically:

import React, { useState, useCallback } from 'react';
import { View } from 'react-native';
import HomeMapplet from '../components/HomeMapplet';

export default function HomeScreen() {
const [appState, setAppState] = useState({
user: { name: 'John Doe', email: 'john@example.com' },
settings: { theme: 'light', notifications: true },
data: { items: [], loading: false }
});

const handleMappletAction = useCallback((action: any) => {
switch (action.type) {
case 'UPDATE_SETTINGS':
setAppState(prev => ({
...prev,
settings: { ...prev.settings, ...action.payload }
}));
break;
case 'LOAD_DATA':
setAppState(prev => ({ ...prev, data: { ...prev.data, loading: true } }));
// Simulate API call
setTimeout(() => {
setAppState(prev => ({
...prev,
data: { items: ['Item 1', 'Item 2'], loading: false }
}));
}, 1000);
break;
default:
console.log('Unhandled action:', action);
}
}, []);

return (
<View style={{ flex: 1 }}>
<HomeMapplet
state={appState}
onAction={handleMappletAction}
/>
</View>
);
}

Best Practices

🚀 Performance Tips
  • Memoization: Use useCallback for action handlers to prevent unnecessary re-renders
  • Component Optimization: Apply React.memo for expensive Mapplet components
  • Immutable Updates: Keep state updates immutable for predictable behavior
  • Lazy Loading: Consider lazy loading for large Mapplets to improve initial load times
⚠️ State Management
  • Keep your state structure flat and organized for better maintainability
  • Use meaningful names for state properties that clearly describe their purpose
  • Provide default values for optional data to prevent undefined errors
  • Structure your state to separate UI state from business logic
📝 Code Organization
  • Keep Mapplets in a dedicated components or mapplets directory for better project structure
  • Use consistent naming conventions (e.g., HomeMapplet, ProfileMapplet) across your project
  • Document your custom Mapplets with JSDoc comments for better developer experience
  • Always handle actions with proper error boundaries and TypeScript for type safety
🎯 Development Best Practices
  • Use TypeScript for action type safety and better development experience
  • Log actions during development for debugging and monitoring
  • Test your Mapplets with different state configurations
  • Follow React best practices for component lifecycle and state management

What's Next?

🎯 Handling Actions

Learn how to handle user interactions and create responsive Mapplets.

Action Handling →

📊 Data State

Discover advanced state management patterns and best practices.

State Management →