|
import Vue from 'vue' |
|
import { createElement as h } from '@vue/composition-api' |
|
import FormulateForm from '@braid/vue-formulate/src/FormulateForm' |
|
const EventBus = new Vue() |
|
|
|
export const FormulateSchema = { |
|
functional: false, |
|
props: { |
|
schema: FormulateForm.props.schema, |
|
nodeHook: { |
|
type: Function, |
|
default: (node) => node, |
|
}, |
|
componentHook: { |
|
type: Function, |
|
default: (node) => h(node.component, node.definition, node.children), |
|
}, |
|
}, |
|
setup(props, { emit }) { |
|
EventBus.$on('events', (payload) => { |
|
emit('events', payload) |
|
}) |
|
/** |
|
* Given an object and an index, complete an object for schema-generation. |
|
* @param {object} item |
|
* @param {int} index |
|
*/ |
|
function leaf(item, index) { |
|
if (item && typeof item === 'object' && !Array.isArray(item)) { |
|
const { children = null, component = 'FormulateInput', depth = 1, events = [], on = {}, ...attrs } = item |
|
const type = component === 'FormulateInput' ? attrs.type || 'text' : '' |
|
const name = attrs.name || type || 'el' |
|
const key = attrs.id || `${name}-${depth}-${index}` |
|
const els = Array.isArray(children) ? children.map((child) => Object.assign(child, { depth: depth + 1 })) : children |
|
const onExtended = { |
|
...on, |
|
...events.reduce((onEvents, event) => { |
|
onEvents[event] = function (payload) { |
|
if (on[event]) on[event](payload) |
|
EventBus.$emit('events', { event, name, type, key, payload }) |
|
} |
|
return onEvents |
|
}, {}), |
|
} |
|
return props.nodeHook(Object.assign({ type, key, depth, component, definition: { attrs, on: onExtended }, children: tree(els) })) |
|
} |
|
return null |
|
} |
|
|
|
/** |
|
* Recursive function to create vNodes from a schema. |
|
* @param {Functon} h createElement |
|
* @param {Array|string} schema |
|
*/ |
|
function tree(schema) { |
|
if (Array.isArray(schema)) { |
|
return schema.map((el) => { |
|
const item = leaf(el) |
|
return props.componentHook(item) |
|
}) |
|
} |
|
return schema |
|
} |
|
|
|
return () => h('div', {}, tree(props.schema)) |
|
}, |
|
} |
|
|
|
export function plugin(instance) { |
|
instance.extend({ |
|
components: { |
|
FormulateSchema, |
|
}, |
|
}) |
|
} |