UNPKG

@ea-lab/reactive-json-docs

Version:

Complete documentation for Reactive-JSON - Components, examples and LLM-parsable guides

221 lines (170 loc) 7.37 kB
# Plugin system guide ## Overview 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. ## Plugin Structure 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 ## Plugin Registration 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. ## Multi-Plugin Application & Plugin Merging When your application needs multiple plugins from different sources, you can combine them using `mergeComponentCollections`. ### Multiple Plugin Usage ```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 ])} /> ); }; ``` ### Component Override Behavior 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} />; }; ``` #### Usage Across Your Application 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} /> ); }; ``` ## Best Practices 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