import type { FormSchema, FormSchemaElement } from '@/types/components' /** * Composable for working with form schemas * Provides utilities for validation, initialization, and manipulation of form schemas */ export function useFormSchema() { /** * Validates that a schema is properly formatted * @param schema - The schema to validate * @returns true if valid, false otherwise */ function validateSchema(schema: FormSchema): boolean { if (!Array.isArray(schema)) { console.warn('[useFormSchema] Schema must be an array') return false } for (const element of schema) { if (!element.component || typeof element.component !== 'string') { console.warn('[useFormSchema] Each schema element must have a component name (string)') return false } if (element.props && typeof element.props !== 'object') { console.warn('[useFormSchema] Element props must be an object') return false } if (element.model && typeof element.model !== 'string') { console.warn('[useFormSchema] Element model must be a string') return false } } return true } /** * Initializes form data object from schema * Creates an object with keys for all model fields in the schema * @param schema - The schema to initialize from * @param defaultValues - Optional default values to use * @returns Initialized form data object */ function initializeFormData( schema: FormSchema, defaultValues: Record = {} ): Record { const formData: Record = { ...defaultValues } for (const element of schema) { if (element.model && !(element.model in formData)) { // Initialize with empty string by default formData[element.model] = '' } } return formData } /** * Gets all model keys from a schema * Useful for validation and form submission * @param schema - The schema to extract model keys from * @returns Array of model keys */ function getModelKeys(schema: FormSchema): string[] { return schema .filter((element) => element.model) .map((element) => element.model as string) } /** * Checks if a component name is a form component * Form components are those that use v-model (have a model property) * @param componentName - The component name to check * @returns true if it's a form component, false otherwise */ function isFormComponent(componentName: string): boolean { const formComponents = [ 'TitanInput', 'TitanTextarea', 'TitanSelect', 'TitanDatePicker', 'TitanImageUpload', ] return formComponents.includes(componentName) } /** * Filters schema to only form components (components with v-model) * @param schema - The schema to filter * @returns Filtered schema with only form components */ function getFormElements(schema: FormSchema): FormSchemaElement[] { return schema.filter((element) => element.model) } /** * Filters schema to only non-form components (like subheaders, dividers) * @param schema - The schema to filter * @returns Filtered schema with only non-form components */ function getNonFormElements(schema: FormSchema): FormSchemaElement[] { return schema.filter((element) => !element.model) } /** * Simple validation helper for required fields * @param formData - The form data to validate * @param schema - The schema to validate against * @returns Object with field names as keys and error messages as values */ function validateRequiredFields( formData: Record, schema: FormSchema ): Record { const errors: Record = {} for (const element of schema) { if (element.model && element.props?.required) { const value = formData[element.model] if (!value || (typeof value === 'string' && value.trim() === '')) { const label = element.props.label || element.model errors[element.model] = `${label} is required` } } } return errors } return { validateSchema, initializeFormData, getModelKeys, isFormComponent, getFormElements, getNonFormElements, validateRequiredFields, } }