@ea-lab/reactive-json-docs
Version:
Complete documentation for Reactive-JSON - Components, examples and LLM-parsable guides
221 lines (170 loc) • 7.37 kB
Markdown
The Reactive-JSON plugin system provides a structured way to organize, distribute, and integrate custom components. Plugins allow you to package related components together and make them available to Reactive-JSON applications through a simple registration mechanism.
A plugin is a JavaScript object that exports components organized by type. The standard plugin structure includes:
- **element**: Display components, form fields, and interactive elements
- **action**: Components that perform side effects or modify behavior
- **reaction**: Event-driven components that respond to user interactions
- **hook**: React hooks that provide additional functionality
- **dataProcessor**: Functions that intercept and modify HTTP response data
- **dataMapping**: Processors that selectively dispatch response data to specific locations
Plugins are registered with the ReactiveJsonRoot component to make components available throughout the application.
First, regroup your components in a plugin object.
```jsx
// myPlugin.js
import { MyButton } from "./components/MyButton.jsx";
import { MyForm } from "./components/MyForm.jsx";
import { MyAction } from "./components/MyAction.jsx";
export const myPlugin = {
element: {
MyButton,
MyForm,
},
action: {
MyAction,
}
};
```
Then, register the plugin with the ReactiveJsonRoot component:
```jsx
import { ReactiveJsonRoot, mergeComponentCollections } from "@ea-lab/reactive-json";
import { myPlugin } from "./plugins/myPlugin.js";
const App = () => {
return (
<ReactiveJsonRoot
plugins={mergeComponentCollections([myPlugin])}
/>
);
};
```
You can now use the components in your RjBuild configuration:
```jsx
import React from 'react';
import { ReactiveJsonRoot, mergeComponentCollections } from "@ea-lab/reactive-json";
import { myPlugin } from "./plugins/myPlugin.js";
const App = () => {
const rjBuildConfig = {
renderView: [
{
type: "MyButton",
content: "Click me!",
customProperty: "some value"
}
],
data: {}
};
return (
<ReactiveJsonRoot
rjBuild={rjBuildConfig}
plugins={mergeComponentCollections([myPlugin])}
/>
);
};
```
The plugin is now available throughout the application.
When your application needs multiple plugins from different sources, you can combine them using `mergeComponentCollections`.
```jsx
import { ReactiveJsonRoot, mergeComponentCollections } from "@ea-lab/reactive-json";
import { chartjsComponents } from "@ea-lab/reactive-json-chartjs";
import { customPlugins } from "./plugins/customPlugins.js";
import { thirdPartyPlugin } from "third-party-reactive-json-plugin";
const App = () => {
return (
<ReactiveJsonRoot
rjBuild={rjBuildConfig}
plugins={mergeComponentCollections([
chartjsComponents,
customPlugins,
thirdPartyPlugin
])}
/>
);
};
```
When using `mergeComponentCollections` with multiple plugins, **the last component with a given name takes precedence**. This allows you to override default components with custom implementations.
```jsx
import { ReactiveJsonRoot, mergeComponentCollections } from "@ea-lab/reactive-json";
import { defaultComponents } from "@ea-lab/reactive-json";
import { customComponents } from "./plugins/customComponents.js";
const plugins = mergeComponentCollections([
defaultComponents, // Contains a "Button" component
customComponents // Also contains a "Button" component - this one will be used
]);
```
This override mechanism is particularly useful for:
- **Customizing default components**: Replace built-in components with your own implementations
- **Theme customization**: Override components to match your design system
- **Feature enhancement**: Add functionality to existing components
- **Third-party integration**: Replace components with versions from external libraries
**Example: Overriding a Default Button**
```jsx
// Default plugin has a basic Button
const defaultPlugin = {
element: {
Button: BasicButton // Simple button implementation
}
};
// Your custom plugin overrides it
const customPlugin = {
element: {
Button: EnhancedButton // Button with animations and custom styling
}
};
// EnhancedButton will be used everywhere "Button" is referenced
const plugins = mergeComponentCollections([defaultPlugin, customPlugin]);
```
**⚠️ Important**: Component names must match exactly (case-sensitive) for the override to work. The order in the `mergeComponentCollections` array determines precedence.
### Custom ReactiveJsonRoot Wrapper
Creating a custom wrapper allows you to **centralize plugin inclusion** across your entire application. Instead of manually importing and merging plugins in every component that uses Reactive-JSON, you define them once in a wrapper component.
#### Benefits of Centralized Plugin Management
- **Consistency**: Ensures all parts of your application have access to the same set of components
- **Maintainability**: Update plugin dependencies in one place
- **Simplicity**: Other components only need to import your wrapper, not individual plugins
- **Standardization**: Enforces a consistent plugin configuration across teams
#### Implementation Example
```jsx
import { ReactiveJsonRoot, mergeComponentCollections } from "@ea-lab/reactive-json";
import { chartjsComponents } from "@ea-lab/reactive-json-chartjs";
import { customPlugins } from "./plugins/customPlugins.js";
import { companyUIComponents } from "@company/reactive-json-ui";
export const CustomReactiveJsonRoot = (props) => {
const additionalProps = {};
// Centralize all plugin dependencies for the entire application
additionalProps.plugins = mergeComponentCollections([
chartjsComponents, // Third-party charting components
customPlugins, // Application-specific components
companyUIComponents // Company-wide design system
]);
const finalProps = { ...props, ...additionalProps };
return <ReactiveJsonRoot {...finalProps} />;
};
```
Once created, your wrapper simplifies usage throughout your application:
```jsx
import { CustomReactiveJsonRoot } from "./components/CustomReactiveJsonRoot";
// Component A
export const Dashboard = () => {
return (
<CustomReactiveJsonRoot rjBuild={dashboardConfig} />
);
};
// Component B
export const ReportPage = () => {
return (
<CustomReactiveJsonRoot rjBuild={reportConfig} />
);
};
```
1. **Group related components** in the same plugin
2. **Use descriptive names** for components and plugins
3. **Document component props** and usage patterns
4. **Provide examples** for complex components
5. **Be intentional with component names** - use unique names unless you specifically want to override existing components
6. **Document overrides** when replacing default components to help other developers understand the customization