Introduction

What can I do with plugins?

Right now plugins for Rendevoz is an experimental feature, but you can already use a lot of apis that Rendevoz provides.

Everything is simple and easy, without pain to learn, and React first.

The plugin apis are pretty simple, highly customized and extensible. If you are an experienced React developer (not need to be so experienced XD), I believe you can get started within minutes.

What can I build?

1. Typescript support

Rendevoz has full support for Typescript definitions. If you are using Typescript to develop a plugin, you can define your custom elements.

// Example of how to define your data model
import {
  BuiltInDraggableElement,
  BuiltInDropOn,
  BuiltInMetaObjectTypes,
  BuiltInObjectTypes,
  BuiltInTabTypes
} from 'rendevoz'

declare module 'rendevoz' {
  export interface CustomTypes {
    MetaObject: BuiltInMetaObjectTypes | 'customEle'
    Object: BuiltInObjectTypes & {
      customEle: {
        specType: 'customEle'
      }
    }
    DropOn: BuiltInDropOn
    DraggableElement: BuiltInDraggableElement
    Tab: BuiltInTabTypes
  }
}

In above code, you define custom meta-object and object, and you will get type hint in apis like api.getObjectStore(type).

2. Custom Tabs

You can design and develop your custom tabs for Rendevoz. It's just like you are building a React application for browser or mobile phones. And below is a code snippet to show you how easy it is.

import { PluginApi } from 'rendevoz'

export default (plugin: PluginApi) => {
    plugin.register.registerTab({
        type: 'first tab',
        content: () => <YourCustomTab plugin={plugin} />
    })
}

const YourCustomTab = ({plugin}: {plugin: PluginApi}) => {
    const metaStore = plugin.api.getMetaStore()
    const allMetaObjects = metaStore.useMetaObjectsMap()
    return (
        <>
            <h1>
            I can find all meta-objects in Rendevoz! 
            And these names will automatically change when their value change!
            </h1>
           {
           Array
           .from(allMetaObjects.values())
           .map(i => 
               <div 
               onClick={() => {
                   metaStore.updateMetaObject({id: i.id, name: 'NEW NAME!'})
               }} 
               key={i.id}>{i.name}</div>
           )} 
        </>
        )
}

Look! With only 30 lines code, you can develop a custom tab for Rendevoz and it will list all meta-objects' names, and if clicked, the meta-object's name will be replaced with a new one.

And of course, just like useState in React, when meta-object's state change, the DOM will automatically change too! (no matter where you update its state, even you can update its state in a class component or common ts file)

3. Custom Meta-Object / Object

First of all, what is the difference between meta-object and object?

Simply put:

  1. Object could have any property on it, representing any data structure you want. But meta-object's properties are fixed and you can not change.

  2. Meta object is the higher level abstraction of object, it means object can be turned to meta-object but not the other way around. After turned into a meta-object, it can have relations with any other meta-objects and be found in database.

More info to see: Meta-object vs Object

// Example Object
type MyCustomObject = {
    specType: 'my-custom-object'
    propOne: string
    propTwo?: number
    propThree: {
        propThreeOne: string
        propThreeTwo: string
        }
    propFour: any
    ...infinite props
}

// Example Meta-Object 
// You can only register new type, but can not change props
type MetaObject = {
    type: CustomTypes['MetaObject']
    name?: string
    description?: string
    coverImgSrc?: string
    objectId?: number
    tags?: number[]
    icon?: string
    color?: string
    attachments?: IMetaAttachment[]
}

4. Custom Editor Element

You can add custom element to Rendevoz's editor. Editor is built on latest version of Slate.js, more info and examples to see on https://www.slatejs.org/examples and https://docs.slatejs.org.

Below is a simple example to show how you can register a custom editor element.

import { PluginApi } from 'rendevoz'
import { RenderElementProps } from 'slate'

export default (plugin: PluginApi) => {
    plugin.register.registerEditorElement({
        type: 'customEle',
        renderElement: props => <CustomEditorElement {...props} plugin={plugin} />
        registerInMenu: {
            addMenu: true,
            slashMenu: true,
            menuType: 'block'
        },
        name: 'Your custom Editor Element',
        isInline: true,
        isVoid: false
    })
}

const CustomEditorElement = (props: RenderElementProps & { plugin: PluginApi }) => {
    return (
        // if your element is inline, you need to add attributes
        // if not, don't add attributes!
        <div {...props.attributes}>
            <div 
                onClick={() => {
                    // send a hello world message!
                    plugin.Rendevoz.Actions.Notification.success({ 
                        message: 'Hello world!!!' 
                    })
                }}>
                Click me to send notification!
            </div>
            // children is necessary for every element!!!
            // You have to place it somewhere even if you don't need it!
            {props.children}
        </div>
}

Last updated