@dynamic-field-kit/vue
v1.3.0
Published
Vue 3 renderer for dynamic-field-kit
Maintainers
Readme
@dynamic-field-kit/vue
Vue 3 adapter for @dynamic-field-kit/core.
This package provides Vue components that render FieldDescription[] and resolve field renderers through the shared registry used by dynamic-field-kit.
Demo app: https://github.com/vannt-dev/dynamic-field-kit-demo
Install
npm install @dynamic-field-kit/core @dynamic-field-kit/vue vueNote: @dynamic-field-kit/core is a shared runtime and should be installed in your app separately. The Vue adapter declares core as a peer dependency to avoid bundling core multiple times across adapters.
- Install with core:
npm install @dynamic-field-kit/core @dynamic-field-kit/vue vue
Exports
DynamicInputFieldInputMultiFieldInputlayoutRegistryfieldRegistryFieldDescriptionFieldTypeKeyFieldRendererPropsPropertiesLayoutConfig
Default layouts are registered automatically when you import the package root.
Built-in layouts:
columnrowgrid(alias:grid-2)responsive
Register field renderers
Register Vue renderers before rendering your form:
import { defineComponent, h } from 'vue';
import { fieldRegistry } from '@dynamic-field-kit/vue';
fieldRegistry.register(
'text',
defineComponent({
name: 'TextFieldRenderer',
props: {
value: { type: String, default: '' },
label: { type: String, default: '' },
},
emits: ['update:value'],
setup(props, { emit }) {
return () =>
h('label', { style: { display: 'grid', gap: '4px' } }, [
h('span', props.label),
h('input', {
value: props.value ?? '',
onInput: (event: Event) => {
emit('update:value', (event.target as HTMLInputElement).value);
},
}),
]);
},
})
);Basic usage
<script setup lang="ts">
import { ref } from 'vue';
import { MultiFieldInput } from '@dynamic-field-kit/vue';
import type { FieldDescription } from '@dynamic-field-kit/core';
const fields: FieldDescription[] = [
{ name: 'username', type: 'text', label: 'Username' },
{ name: 'email', type: 'text', label: 'Email' },
];
const formData = ref({});
function handleChange(data: Record<string, unknown>) {
formData.value = data;
}
</script>
<template>
<MultiFieldInput
:fieldDescriptions="fields"
:properties="formData"
:onChange="handleChange"
/>
</template>Layouts
Use a layout name:
<MultiFieldInput :fieldDescriptions="fields" layout="grid" />Use a layout config object:
<MultiFieldInput
:fieldDescriptions="fields"
:layout="{ type: 'grid', columns: 3, gap: 12 }"
/>Use the built-in responsive layout:
<MultiFieldInput
:fieldDescriptions="fields"
:layout="{
type: 'responsive',
mobile: 'column',
desktop: { type: 'grid', columns: 2, gap: 12 },
}"
/>Register a custom layout:
import { h } from 'vue';
import { layoutRegistry } from '@dynamic-field-kit/vue';
layoutRegistry.register('stack-tight', ({ children }) => {
return h('div', { style: { display: 'grid', gap: '8px' } }, children);
});Derived fields with computeValue
Give a field a computeValue to derive its value from the rest of the form data whenever any field changes:
const fields: FieldDescription[] = [
{ name: 'firstName', type: 'text' },
{ name: 'lastName', type: 'text' },
{
name: 'fullName',
type: 'text',
computeValue: (data) =>
`${data.firstName ?? ''} ${data.lastName ?? ''}`.trim(),
},
];Repeatable field groups
A field with fields renders as a repeatable group: data[name] becomes an array of items, each shaped by the nested fields, with "Add"/"Remove" controls rendered automatically.
const fields: FieldDescription[] = [
{
name: 'contacts',
type: 'group',
label: 'Contacts',
fields: [
{ name: 'email', type: 'text', label: 'Email' },
{ name: 'phone', type: 'text', label: 'Phone' },
],
defaultItem: { email: '', phone: '' },
minItems: 1,
maxItems: 5,
},
];<MultiFieldInput :fieldDescriptions="fields" />Type augmentation
import '@dynamic-field-kit/core';
declare module '@dynamic-field-kit/core' {
interface FieldTypeMap {
text: string;
number: number;
}
}Notes
@dynamic-field-kit/coreowns the schema types and shared runtime registry.@dynamic-field-kit/vueis the package you should import when registering Vue renderers.MultiFieldInputfilters fields usingappearConditionand derives fields usingcomputeValue.DynamicInputrendersUnknown field type: ...when a renderer is missing.- Fields with
fieldsrender as repeatable groups instead of going throughfieldRegistry.
License
MIT
