App Builder Component Documentation
Overview
The App Builder is a visual tool that lets you create user interfaces by dragging and dropping components onto a canvas. Its architecture is built for extensibility, making it easy to add new, custom components.
The system is powered by a Component Registry, a central file that automatically finds and configures new components. To add a new component, you just create a few files in a specific folder structure and then add one line of code to the registry.
How to Create a New Component
Creating a new component is a standardized process that involves 4-5 files within a dedicated folder. This guide will walk you through creating a hypothetical "Call to Action" component.
Step 1: Create the Component Directory
First, go to the components directory and create a new folder for your component. The folder name should be capitalized and descriptive.
valstorm-components-15/components/AppBuilder/components/CallToAction/
Step 2: Define Default Properties (CallToAction.props.js)
This file defines the component's default state and metadata. This data is used when you first drag the component from the side panel onto the canvas.
.../CallToAction/CallToAction.props.js
export const CallToActionProps = {
// --- Metadata for the UI and Registry ---
api_name: "call_to_action", // A unique, lowercase, snake_case key for the component
name: "Call to Action", // The human-friendly name shown in the UI panel
category: "Marketing", // The category it will appear under in the left panel
component_type: "CallToAction", // The name of the React component to render
schema_name: "call_to_action", // A unique key to link to the settings schema
// --- Default properties for the component's state ---
button_text: "Click Me!",
title_text: "Join Our Newsletter",
variant: "contained", // e.g., 'contained', 'outlined'
class_name: "flex flex-col p-1"
};
Step 3: Define the Settings Schema (CallToAction.schema.js)
This file uses a standard JSON Schema format to define the fields that will automatically appear in the right-side Settings Panel. The property keys here should match the keys in your props.js file.
.../CallToAction/CallToAction.schema.js
export const CallToActionSchema = {
title: "Call to Action",
description: "Configuration for the Call to Action component.",
properties: {
// This property is required for all components. It allows the user
// to give a unique name to this specific instance of the component.
"api_name": {
"type": "string",
"title": "API Name (Unique)",
"description": "A unique name for this component instance."
},
// Define other fields that you want to be configurable.
"title_text": {
"type": "string",
"title": "Title Text",
"description": "The main headline for the call to action."
},
"button_text": {
"type": "string",
"title": "Button Text",
},
"variant": {
"type": "string",
"title": "Button Variant",
"enum": ["contained", "outlined", "text"] // Creates a dropdown
},
// Use "custom_setting": true for complex properties that will be
// handled by a custom .settings.jsx component instead of this schema.
"complex_property": {
"type": "object",
"title": "Advanced Settings",
"custom_setting": true
}
},
required: ["api_name", "button_text"] // A list of required fields.
};
Step 4: Create the Visual Component (CallToAction.component.jsx)
This is the React component that renders the visual representation of your component on the canvas. It receives a props object which contains the node (its current state and data) and handlers like handleClick.
.../CallToAction/CallToAction.component.jsx
import React, { memo } from 'react';
import { Button, Typography } from '@mui/material';
// The component is wrapped in memo for performance.
// It receives a single 'props' object containing everything it needs.
export const CallToAction = memo(({ props }) => {
// Destructure the node and handlers from the main props object.
const { node, handleClick } = props;
// Destructure the component's specific data from node.props.
const { title_text, button_text, variant, class_name } = node.props;
return (
// The main div calls handleClick to make the component selectable in the builder.
<div
className={class_name}
onClick={(e) => handleClick(e, node)}
style={{ padding: '16px', border: '1px dashed #ccc', textAlign: 'center' }}
>
<Typography variant="h5">{title_text}</Typography>
<Button variant={variant} color="primary" sx={{ mt: 2 }}>
{button_text}
</Button>
</div>
);
});
Step 5 (Optional): Create Custom Settings UI (CallToAction.settings.jsx)
If your component has complex settings that can't be represented by the simple schema fields (like the MUI Grid component), you can create an optional custom settings component.
.../CallToAction/CallToAction.settings.jsx
import React from 'react';
import { ListItem, FormLabel, Switch } from '@mui/material';
// The component receives the current node and handlers to update the state.
export const CallToActionSettings = ({ node, handleChange, handleNodeChange }) => {
const handleToggle = (event) => {
// For complex updates, you can modify a copy of the node
// and pass the entire new node to the parent.
const newNode = JSON.parse(JSON.stringify(node));
newNode.props.someComplexValue = event.target.checked;
handleNodeChange(newNode);
};
return (
<ListItem>
<FormLabel>Advanced Option</FormLabel>
<Switch
checked={node.props.someComplexValue || false}
onChange={handleToggle}
/>
</ListItem>
);
};
Step 6: Create the Unified Export (index.js)
This file bundles all the pieces of your component into a single, structured object that the Component Registry can easily consume.
.../CallToAction/index.js
import { CallToAction } from './CallToAction.component';
import { CallToActionProps } from './CallToAction.props';
import { CallToActionSchema } from './CallToAction.schema';
// Import the custom settings if you created one.
import { CallToActionSettings } from './CallToAction.settings';
export const CallToActionComponent = {
component: CallToAction,
props: CallToActionProps,
schema: CallToActionSchema,
// If the component has custom settings, add the 'settings' key.
// If not, you can omit this line.
settings: CallToActionSettings,
};
Step 7: Register the New Component
This is the final and most important step. Open the central registry file and tell it about your new component.
.../AppBuilder/ComponentRegistry.js
// ... other component imports
import { MuiGridComponent } from './components/Layout/Grid';
import { CallToActionComponent } from './components/CallToAction'; // 1. Import your new component
// The list of all raw component definitions
const allComponentDefinitions = [
DropZoneComponent,
HeaderOneComponent,
MuiGridComponent,
CallToActionComponent, // 2. Add your component to this list
// ... add other components here
];
// ... the rest of the file (no other changes needed)
After completing these steps, your "Call to Action" component will automatically be available in the App Builder panel, ready to be used.