Hello all!
I am working on a project that uses Vue 3 and vuetify that requires me to implement custom renderers.
As a first step a tried coping the vuetify string component renderer and importing it as a custom renderer which worked fine.
The second step involves rewriting the component in vue3 composition syntax and then finally on step 3 replacing the template with vuetify components for the projects needs.
I ran into difficulty after refactoring the existing component to the new syntax and i am getting the following error
displayOnlyRenderer.vue:1 [Vue warn]: Component is missing template or render function.
As stated before the form displays without a problem in the old syntax so i figure the error is not originating from the schema / ui schema / data.
The component in the composition syntax:
<script setup lang="ts">
import { ControlElement } from '@jsonforms/core';
import { RendererProps, useJsonFormsControl } from '@jsonforms/vue';
import { ControlWrapper, useVuetifyControl } from '@jsonforms/vue-vuetify';
import { computed } from 'vue';
import { VCombobox, VHover, VTextField } from 'vuetify/lib/components/index.mjs';
const props = defineProps<RendererProps<ControlElement>>();
const { control,
//handleChange,
styles,
isFocused,
appliedOptions,
controlWrapper,
onChange,
vuetifyProps,
persistentHint,
computedLabel,
} =
useVuetifyControl
(useJsonFormsControl(props),
(value) => value || undefined,
300);
const suggestions = computed(() : string[] | undefined => {
return undefined;
});
</script>
<template>
<control-wrapper
v-bind="controlWrapper"
:styles="styles"
:isFocused="isFocused"
:appliedOptions="appliedOptions"
>
<v-hover v-slot="{ isHovering }">
<v-combobox
v-if="suggestions !== undefined"
:id="control.id + '-input'"
:class="styles.control.input"
:disabled="!control.enabled"
:autofocus="appliedOptions.focus"
:placeholder="appliedOptions.placeholder"
:label='computedLabel'
:hint="control.description"
:persistent-hint="persistentHint()"
:required="control.required"
:error-messages="control.errors"
:maxlength="
appliedOptions.restrict ? control.schema.maxLength : undefined
"
:counter="
control.schema.maxLength !== undefined
? control.schema.maxLength
: undefined
"
:clearable="isHovering"
:model-value="control.data"
:items="suggestions"
hide-no-data
v-bind="vuetifyProps('v-combobox')"
@update:model-value="onChange"
@focus="isFocused = true"
@blur="isFocused = false"
/>
<v-text-field
v-else
:id="control.id + '-input'"
:class="styles.control.input"
:disabled="!control.enabled"
:autofocus="appliedOptions.focus"
:placeholder="appliedOptions.placeholder"
:label='computedLabel'
:hint="control.description"
:persistent-hint="persistentHint()"
:required="control.required"
:error-messages="control.errors"
:model-value="control.data"
:maxlength="
appliedOptions.restrict ? control.schema.maxLength : undefined
"
:counter="
control.schema.maxLength !== undefined
? control.schema.maxLength
: undefined
"
:clearable="isHovering"
v-bind="vuetifyProps('v-text-field')"
@update:model-value="onChange"
@focus="isFocused = true"
@blur="isFocused = false"
/>
</v-hover>
</control-wrapper>
</template>
The renderer is added in the following way -
function buildRendererRegistryEntry(testRenderer: any, controlType: Tester) {
const entry: JsonFormsRendererRegistryEntry = {
renderer: testRenderer,
tester: rankWith(3, controlType),
};
return entry;
}
export const displayOnlyCustomRenderer = buildRendererRegistryEntry(DisplayOnlyRenderer, isStringControl);
const renderers = [
//...vuetifyRenderers,
displayOnlyCustomRenderer
];
Object.freeze(renderers
Thank you for the help!