- Added functionality for resizing components within the Form Builder, allowing users to adjust widths dynamically. - Introduced a method to find optimal grid placement for new components, ensuring efficient use of available space. - Enhanced layout optimization after component addition, deletion, and reordering to maintain a clean and organized interface. - Updated the FormBuilderConfiguration to include width settings for components, improving customization options. - Refactored styles for grid layout and component previews to enhance visual consistency and user experience.
102 lines
2.9 KiB
Vue
102 lines
2.9 KiB
Vue
<template>
|
|
<div class="component-preview" :style="componentStyle">
|
|
<!-- 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);
|
|
});
|
|
|
|
// Compute style based on grid properties
|
|
const componentStyle = computed(() => {
|
|
// Only apply grid styles in the non-preview mode (actual form)
|
|
if (props.isPreview) {
|
|
return {}; // Styling is handled by parent in canvas mode
|
|
}
|
|
|
|
// Apply grid column in preview mode
|
|
const gridColumn = props.component.props.gridColumn || 'span 12';
|
|
|
|
return {
|
|
gridColumn: gridColumn,
|
|
width: '100%', // Always use 100% within the grid cell
|
|
boxSizing: 'border-box'
|
|
};
|
|
});
|
|
</script>
|
|
|
|
<style scoped>
|
|
.component-preview {
|
|
width: 100%;
|
|
}
|
|
</style> |