mitlist/fe/src/components/valerie/VFormField.vue

66 lines
1.9 KiB
Vue

<template>
<div class="form-group">
<label v-if="label" :for="forId" class="form-label">{{ label }}</label>
<slot></slot>
<p v-if="errorMessage" class="form-error-message">{{ errorMessage }}</p>
</div>
</template>
<script lang="ts">
import { defineComponent, computed } from 'vue';
export default defineComponent({
name: 'VFormField',
props: {
label: {
type: String,
default: null,
},
// 'for' is a reserved keyword in JS, so often component props use 'htmlFor' or similar.
// However, Vue allows 'for' in props directly. Let's stick to 'forId' for clarity to avoid confusion.
forId: {
type: String,
default: null,
},
errorMessage: {
type: String,
default: null,
},
},
setup(props) {
// No specific setup logic needed for this component's current requirements.
// Props are directly used in the template.
return {};
},
});
</script>
<style lang="scss" scoped>
.form-group {
margin-bottom: 1rem; // Spacing between form fields
}
.form-label {
display: block;
margin-bottom: 0.5rem; // Space between label and input
font-weight: 500;
// Add other label styling as needed from design system
// e.g., color: var(--label-color);
}
.form-error-message {
margin-top: 0.25rem; // Space between input and error message
font-size: 0.875em; // Smaller text for error messages
color: #dc3545; // Example error color (Bootstrap's danger color)
// Replace with SCSS variable: var(--danger-color) or similar
// Add other error message styling as needed
}
// Styling for slotted content (inputs, textareas, etc.) will typically
// be handled by those components themselves (e.g., VInput, VTextarea).
// However, you might want to ensure consistent width or display:
// ::v-deep(input), ::v-deep(textarea), ::v-deep(select) {
// width: 100%; // Example to make slotted inputs take full width of form-group
// }
</style>