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:
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.
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