How to Implement Custom Editor Panels for Plugin Properties in Luban H5

Set custom: true in your plugin definition and provide a lazy-loaded Vue component via the editor field to replace the generic right-panel form with a specialized property interface.

Luban H5 is an open-source visual page builder that relies on a plugin-based architecture for its components. While the default right-panel UI handles standard property editing, complex plugins often require specialized interfaces for rich configuration. This guide explains how to implement custom editor panels for plugin properties in Luban H5 by leveraging the custom flag, lazy-loaded editor components, and the core rendering logic in props.js.

How Luban H5 Discovers Custom Editors

The editor follows a four-step resolution process to determine whether to render a generic form or a custom Vue component.

Plugin Registration with the custom Flag

In the plugin's main entry file, setting custom: true signals to the core that this component provides its own property editor. The editor property points to a Vue component that the core loads lazily.

In front-end/h5/src/components/core/plugins/lbp-slide.js, you can see this pattern in production plugins.

Right-Panel Rendering Logic

The file front-end/h5/src/components/core/editor/right-panel/props.js contains the logic that reads the plugin's prop schema. When it encounters custom: true at the plugin level, it imports and renders the component specified in the editor field instead of the default form generator.

Prop-Level Customization

Individual properties within the schema can also declare custom: true. This allows fine-grained control where specific fields use dedicated sub-editors (such as color pickers or table editors) while other fields remain generic.

Required Files and Project Structure

To implement a custom editor panel, you will create or modify the following files:

File Path Purpose Required Changes
front-end/h5/src/components/core/plugins/<your-plugin>.js Plugin registration and schema definition Add custom: true and editor: () => import('./editor.vue')
front-end/h5/src/components/core/plugins/<your-plugin>/editor.vue Custom property panel UI Implement the Vue component using Luban UI primitives like LbFormItem and LbInput
front-end/h5/src/components/core/editor/right-panel/props.js Core rendering logic No changes required unless extending the loader

Step-by-Step Implementation

Step 1: Create the Plugin Entry

Define your plugin with the custom flag and lazy-loaded editor path.

// front-end/h5/src/components/core/plugins/my-plugin.js
import MyComponent from './MyComponent.vue'

export default {
  name: 'my-plugin',
  component: MyComponent,

  // ★ Tell Luban to use a custom property editor
  custom: true,

  // Path to the editor UI (lazy‑loaded)
  editor: () => import('./editor.vue'),

  // Example of a prop that also uses a custom sub‑editor
  props: {
    items: {
      type: Array,
      default: () => [],
      // Each item will be edited by a dedicated sub‑editor
      custom: true
    }
  }
}

Step 2: Build the Custom Editor Component

Create the Vue component that renders in the right panel. Use Luban's UI primitives and Vuex helpers to bind data.

<template>
  <div class="my-plugin-editor">
    <lb-form-item :label="$t('items')">
      <lb-button type="primary" @click="addItem">
        {{ $t('addItem') }}
      </lb-button>
    </lb-form-item>

    <div v-for="(item, i) in value.items" :key="i" class="item-row">
      <lb-input v-model="item.text" :placeholder="$t('itemText')" />
      <lb-button @click="removeItem(i)">{{ $t('remove') }}</lb-button>
    </div>
  </div>
</template>

<script>
import { mapState, mapMutations } from 'vuex'
export default {
  name: 'MyPluginEditor',
  computed: {
    // `editingElement` is the element currently selected in the canvas
    ...mapState('editor', ['editingElement']),
    // Shortcut to plugin‑specific data
    value() {
      return this.editingElement
    }
  },
  methods: {
    ...mapMutations('editor', ['updateEditingElement']),
    addItem() {
      const items = [...this.value.items, { text: '' }]
      this.updateEditingElement({ items })
    },
    removeItem(idx) {
      const items = this.value.items.filter((_, i) => i !== idx)
      this.updateEditingElement({ items })
    }
  }
}
</script>

<style scoped>
.item-row {
  display: flex;
  align-items: center;
  margin-top: 8px;
}
</style>

Key Source Files Reference

Understanding the core implementation helps debug custom editors. These files handle the detection and rendering logic:

Best Practices and Performance Tips

When building custom editor panels for Luban H5 plugins, follow these guidelines to ensure maintainability and performance:

  • Use lazy loading – Always define the editor property as a function returning a dynamic import: editor: () => import('./editor.vue'). The core system invokes this function only when the user selects your plugin, keeping the initial application bundle small.
  • Bind to Vuex correctly – Access the selected element via mapState('editor', ['editingElement']) and commit changes through mapMutations('editor', ['updateEditingElement']). This ensures that modifications in your custom right-panel are immediately reflected on the canvas and persisted with the project data.
  • Scope your styles – Always add scoped to the <style> tag in editor.vue to prevent CSS leaks into the canvas or other editor panels.
  • Leverage Luban UI primitives – Use LbFormItem, LbInput, LbButton, and LbSelect instead of raw HTML elements to maintain visual consistency with the rest of the builder.
  • Internationalize labels – Use $t('key') for all user-facing strings, adding keys to src/locales/lang/*.js to support multiple languages.

Summary

To implement custom editor panels for plugin properties in Luban H5:

  • Set custom: true in your plugin definition to signal the core to bypass the generic form.
  • Provide an editor function that lazy-loads your Vue component (e.g., editor: () => import('./editor.vue')).
  • Build the editor component using Luban UI primitives and Vuex helpers (mapState, mapMutations) to bind to the selected canvas element.
  • Optionally mark individual props with custom: true for fine-grained control over specific fields.

The core logic in front-end/h5/src/components/core/editor/right-panel/props.js handles the rest, automatically swapping the default panel for your custom implementation whenever users select your plugin on the canvas.

Frequently Asked Questions

How does Luban H5 decide when to show a custom editor versus the default property form?

The right-panel controller in front-end/h5/src/components/core/editor/right-panel/props.js inspects the selected plugin's schema. If the plugin object contains custom: true, the core imports the component specified in the editor field and renders it instead of iterating through the generic prop schema. If custom is falsy or omitted, the system falls back to the standard form generator.

Can I use a custom editor for just one specific property while keeping the rest generic?

Yes. You can mark individual properties with custom: true inside the props definition. When the generic form generator encounters a prop with this flag, it looks for a dedicated editor component for that specific field while rendering standard inputs for all other properties. This hybrid approach allows you to build specialized interfaces for complex fields without reimplementing the entire panel.

Always use the Vuex store module editor provided by Luban H5. Access the currently selected element via mapState('editor', ['editingElement']) and commit changes using mapMutations('editor', ['updateEditingElement']). This ensures that modifications in your custom right-panel are immediately reflected on the canvas and persisted with the project data. Directly mutating the element object without the mutation may cause reactivity issues or break undo/redo functionality.

Does implementing a custom editor affect the initial bundle size of the Luban H5 builder?

No, provided you use lazy loading. Define the editor property as a function returning a dynamic import: editor: () => import('./editor.vue'). The core system invokes this function only when the user selects your plugin, causing the custom editor code to be fetched on demand. This keeps the initial application bundle small and improves startup performance for the page builder.```markdown

Set custom: true in your plugin definition and provide a Vue component via the editor field to replace the generic right-panel form with a specialized property interface.

Luban H5 is an open-source visual page builder that relies on a plugin-based architecture for its components. While the default right-panel UI handles basic property editing, complex plugins often require specialized interfaces for rich configuration. This guide explains how to implement custom editor panels for plugin properties in Luban H5 by leveraging the custom flag, lazy-loaded editor components, and the core rendering logic in props.js.

How Luban H5 Discovers Custom Editors

The editor follows a four-step resolution process to determine whether to render a generic form or a custom Vue component.

Plugin Registration with the custom Flag

In the plugin's main entry file, setting custom: true signals to the core that this component provides its own property editor. The editor property points to a Vue component that the core loads lazily.

In front-end/h5/src/components/core/plugins/lbp-slide.js, you can see this pattern in production plugins.

Right-Panel Rendering Logic

The file front-end/h5/src/components/core/editor/right-panel/props.js contains the logic that reads the plugin's prop schema. When it encounters custom: true at the plugin level, it imports and renders the component specified in the editor field instead of the default form generator.

Prop-Level Customization

Individual properties within the schema can also declare custom: true. This allows fine-grained control where specific fields use dedicated sub-editors (such as color pickers or table editors) while other fields remain generic.

Required Files and Project Structure

To implement a custom editor panel, you will create or modify the following files:

File Path Purpose Required Changes
front-end/h5/src/components/core/plugins/<your-plugin>.js Plugin registration and schema definition Add custom: true and editor: () => import('./editor.vue')
front-end/h5/src/components/core/plugins/<your-plugin>/editor.vue Custom property panel UI Implement the Vue component using Luban UI primitives like LbFormItem and LbInput
front-end/h5/src/components/core/editor/right-panel/props.js Core rendering logic No changes required unless extending the loader

Step-by-Step Implementation

Step 1: Create the Plugin Entry

Define your plugin with the custom flag and lazy-loaded editor path.

// front-end/h5/src/components/core/plugins/my-plugin.js
import MyComponent from './MyComponent.vue'

export default {
  name: 'my-plugin',
  component: MyComponent,

  // ★ Tell Luban to use a custom property editor
  custom: true,

  // Path to the editor UI (lazy‑loaded)
  editor: () => import('./editor.vue'),

  // Example of a prop that also uses a custom sub‑editor
  props: {
    items: {
      type: Array,
      default: () => [],
      // Each item will be edited by a dedicated sub‑editor
      custom: true
    }
  }
}

Step 2: Build the Custom Editor Component

Create the Vue component that renders in the right panel. Use Luban's UI primitives and Vuex helpers to bind data.

<template>
  <div class="my-plugin-editor">
    <lb-form-item :label="$t('items')">
      <lb-button type="primary" @click="addItem">
        {{ $t('addItem') }}
      </lb-button>
    </lb-form-item>

    <div v-for="(item, i) in value.items" :key="i" class="item-row">
      <lb-input v-model="item.text" :placeholder="$t('itemText')" />
      <lb-button @click="removeItem(i)">{{ $t('remove') }}</lb-button>
    </div>
  </div>
</template>

<script>
import { mapState, mapMutations } from 'vuex'
export default {
  name: 'MyPluginEditor',
  computed: {
    // `editingElement` is the element currently selected in the canvas
    ...mapState('editor', ['editingElement']),
    // Shortcut to plugin‑specific data
    value() {
      return this.editingElement
    }
  },
  methods: {
    ...mapMutations('editor', ['updateEditingElement']),
    addItem() {
      const items = [...this.value.items, { text: '' }]
      this.updateEditingElement({ items })
    },
    removeItem(idx) {
      const items = this.value.items.filter((_, i) => i !== idx)
      this.updateEditingElement({ items })
    }
  }
}
</script>

<style scoped>
.item-row {
  display: flex;
  align-items: center;
  margin-top: 8px;
}
</style>

Key Source Files Reference

Understanding the core implementation helps debug custom editors. These files handle the detection and rendering logic:

  • front-end/h5/src/components/core/editor/right-panel/props.js – Core logic that inspects the plugin schema and renders either the generic form or the custom editor component.
  • front-end/h5/src/components/core/plugins/lbp-slide.js – Production example demonstrating the custom: true flag.
  • docs/zh/plugin-development/how-it-works/custom-editor-single-prop.md – Documentation for single-property custom editors.
  • docs/zh/plugin-development/how-it-works/custom-editor-multiple-props.md – Documentation for multi-property custom editors.

Best Practices and Performance Tips

When building custom editor panels for Luban H5 plugins, follow these guidelines to ensure maintainability and performance:

  • Use lazy loading – Always define the editor property as a function returning a dynamic import: editor: () => import('./editor.vue'). This prevents the custom editor code from bloating the initial bundle.
  • Bind to Vuex correctly – Access the selected element via mapState('editor', ['editingElement']) and commit changes using mapMutations('editor', ['updateEditingElement']). This ensures that modifications in your custom right-panel are immediately reflected on the canvas and persisted with the project data.
  • Scope your styles – Always add scoped to the <style> tag in editor.vue to prevent CSS leaks into the canvas.
  • Leverage Luban UI primitives – Use LbFormItem, LbInput, LbButton, and LbSelect instead of raw HTML elements to maintain visual consistency with the rest of the builder.
  • Internationalize labels – Use $t('key') for all user-facing strings, adding keys to src/locales/lang/*.js to support multiple languages.

Summary

To implement custom editor panels for plugin properties in Luban H5:

  • Set custom: true in your plugin definition to signal the core to bypass the generic form.
  • Provide an editor function that lazy-loads your Vue component (e.g., editor: () => import('./editor.vue')).
  • Build the editor component using Luban UI primitives and Vuex helpers (mapState, mapMutations) to bind to the selected canvas element.
  • Optionally mark individual props with custom: true for fine-grained control over specific fields.

The core logic in front-end/h5/src/components/core/editor/right-panel/props.js handles the rest, automatically swapping the default panel for your custom implementation whenever users select your plugin on the canvas.

Frequently Asked Questions

How does Luban H5 decide when to show a custom editor versus the default property form?

The right-panel controller in front-end/h5/src/components/core/editor/right-panel/props.js inspects the selected plugin's schema. If the plugin object contains custom: true, the core imports the component specified in the editor field and renders it instead of iterating through the generic prop schema. If custom is falsy or omitted, the system falls back to the standard form generator.

Can I use a custom editor for just one specific property while keeping the rest generic?

Yes. You can mark individual properties with custom: true inside the props definition. When the generic form generator encounters a prop with this flag, it looks for a dedicated editor component for that specific field while rendering standard inputs for all other properties. This hybrid approach allows you to build specialized interfaces for complex fields without reimplementing the entire panel.

Always use the Vuex store module editor provided by Luban H5. Access the currently selected element via mapState('editor', ['editingElement']) and commit changes using mapMutations('editor', ['updateEditingElement']). This ensures that modifications in your custom right-panel are immediately reflected on the canvas and persisted with the project data. Directly mutating the element object without the mutation may cause reactivity issues or break undo/redo functionality.

Does implementing a custom editor affect the initial bundle size of the Luban H5 builder?

No, provided you use lazy loading. Define the editor property as a function returning a dynamic import: editor: () => import('./editor.vue'). The core system invokes this function only when the user selects your plugin, causing the custom editor code to be fetched on demand. This keeps the initial application bundle small and improves startup performance for the page builder.```

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →