corrad-bp/components/ComponentPreview.vue
Md Afiq Iskandar 316420282b Add form builder components and functionality
- Introduced `FormBuilderComponents.vue`, `FormBuilderCanvas.vue`, and `FormBuilderConfiguration.vue` for managing form elements.
- Added `ComponentPreview.vue` for rendering previews of form components.
- Implemented state management using Pinia in `stores/formBuilder.js` to handle form components and saved forms.
- Created pages for form builder interface (`index.vue`) and form management (`manage.vue`).
- Integrated toast notifications with `useToast.js` for user feedback.
- Documented the form builder structure and features in `FORM_BUILDER_DOCUMENTATION.md` and `FORM_BUILDER_TECHNICAL_APPENDIX.md`.
- Established a responsive layout and drag-and-drop functionality for a seamless user experience.
2025-04-09 12:18:50 +08:00

85 lines
2.4 KiB
Vue

<template>
<div class="component-preview">
<!-- Basic Input Types -->
<FormKit
v-if="isInputType"
:id="`preview-${component.id}`"
:type="component.props.type"
:name="component.props.name"
:label="component.props.label"
:help="component.props.help"
:placeholder="component.props.placeholder"
:validation="component.props.validation"
:validation-visibility="isPreview ? 'live' : 'blur'"
:disabled="isPreview"
:options="component.props.options || undefined"
:value="component.props.value || undefined"
:accept="component.props.accept || undefined"
:max="component.props.max || undefined"
:preserve-events="isPreview"
@input.capture.stop="isPreview ? $event.stopPropagation() : null"
@click.capture.stop="isPreview ? $event.stopPropagation() : null"
/>
<!-- Heading -->
<div v-else-if="component.type === 'heading'" class="py-2">
<component
:is="`h${component.props.level || 2}`"
class="font-semibold"
:class="{
'text-2xl': component.props.level === 2,
'text-xl': component.props.level === 3,
'text-lg': component.props.level === 4
}"
>
{{ component.props.value }}
</component>
</div>
<!-- Paragraph -->
<div v-else-if="component.type === 'paragraph'" class="py-2">
<p class="text-gray-600">{{ component.props.value }}</p>
</div>
<!-- Divider -->
<div v-else-if="component.type === 'divider'" class="py-4">
<hr class="border-gray-200" />
</div>
<!-- Unknown Component Type Fallback -->
<div v-else class="p-4 border border-dashed border-gray-300 rounded">
<div class="text-gray-500">Unknown component type: {{ component.type }}</div>
</div>
</div>
</template>
<script setup>
const props = defineProps({
component: {
type: Object,
required: true
},
isPreview: {
type: Boolean,
default: false
}
});
// Check if the component is a standard FormKit input type
const isInputType = computed(() => {
const inputTypes = [
'text', 'textarea', 'number', 'email', 'password',
'date', 'time', 'datetime-local', 'url', 'tel',
'select', 'checkbox', 'radio', 'file', 'range',
'color', 'hidden', 'group', 'repeater'
];
return inputTypes.includes(props.component.type);
});
</script>
<style scoped>
.component-preview {
width: 100%;
}
</style>