bnk-components
Version:
Reusable React components for Issaglam UI - Modern, responsive UI components with TypeScript support
111 lines (110 loc) • 6.02 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { useState, useCallback, useContext } from 'react';
import { createFormField } from './ComponentFactory';
import { FormContext } from '../CrudGrid/CrudGrid';
import './AutoForm.css';
export function AutoForm({ metadata, data, onChange, onSubmit, onCancel, loading = false, readOnly = false, className = '' }) {
const [errors, setErrors] = useState({});
const formContext = useContext(FormContext);
// Field değişiklik handler'ı
const handleFieldChange = useCallback((fieldName, value) => {
// Validation
const field = metadata.fields.find(f => f.name === fieldName);
if (field) {
const error = validateField(field, value);
setErrors(prev => (Object.assign(Object.assign({}, prev), { [fieldName]: error || '' })));
}
// FormContext aracılığıyla değişikliği ilet
if (formContext && formContext.onFieldChange) {
formContext.onFieldChange(fieldName, value);
}
// Parent onChange çağır
onChange(fieldName, value);
}, [metadata, onChange, formContext]);
// Field validation
const validateField = (field, value) => {
const { validation } = field;
if (!validation)
return null;
// Required validation
if (validation.required && (!value || value === '')) {
return `${field.label || field.name} zorunludur`;
}
// Min length validation
if (validation.minLength && value && value.length < validation.minLength) {
return `${field.label || field.name} en az ${validation.minLength} karakter olmalıdır`;
}
// Max length validation
if (validation.maxLength && value && value.length > validation.maxLength) {
return `${field.label || field.name} en fazla ${validation.maxLength} karakter olmalıdır`;
}
// Min value validation
if (validation.min !== undefined && value !== undefined && Number(value) < validation.min) {
return `${field.label || field.name} en az ${validation.min} olmalıdır`;
}
// Max value validation
if (validation.max !== undefined && value !== undefined && Number(value) > validation.max) {
return `${field.label || field.name} en fazla ${validation.max} olmalıdır`;
}
// Pattern validation
if (validation.pattern && value && !new RegExp(validation.pattern).test(value)) {
return `${field.label || field.name} geçerli formatta değil`;
}
// Custom validation
if (validation.custom) {
return validation.custom(value);
}
return null;
};
// Form submit handler
const handleSubmit = useCallback((e) => {
e.preventDefault();
// Tüm field'ları validate et
const newErrors = {};
metadata.fields.forEach(field => {
const error = validateField(field, data[field.name]);
if (error) {
newErrors[field.name] = error;
}
});
setErrors(newErrors);
// Eğer hata yoksa submit et
if (Object.keys(newErrors).length === 0 && onSubmit) {
onSubmit(data);
}
}, [metadata, data, onSubmit]);
// Form cancel handler
const handleCancel = useCallback(() => {
if (onCancel) {
onCancel();
}
}, [onCancel]);
// Field render function
const renderField = (field) => {
const FieldComponent = createFormField(field);
const value = data[field.name];
const error = errors[field.name];
return (_jsx(FieldComponent, { field: field, value: value, onChange: (value) => handleFieldChange(field.name, value), error: error, disabled: loading, readOnly: readOnly }, field.name));
};
// Layout'a göre field'ları grupla
const renderFields = () => {
const { fields, layout = 'single', sections } = metadata;
if (sections && sections.length > 0) {
// Section'lı layout
return sections.map((section, index) => (_jsxs("div", { className: "auto-form-section", children: [_jsx("h3", { className: "auto-form-section-title", children: section.title }), _jsx("div", { className: "auto-form-section-content", children: section.fields.map(fieldName => {
const field = fields.find(f => f.name === fieldName);
return field ? renderField(field) : null;
}) })] }, index)));
}
// Layout'a göre field'ları grupla
switch (layout) {
case 'two-column':
return (_jsx("div", { className: "auto-form-two-column", children: fields.map((field, index) => (_jsx("div", { className: "auto-form-field-wrapper", children: renderField(field) }, field.name))) }));
case 'three-column':
return (_jsx("div", { className: "auto-form-three-column", children: fields.map((field, index) => (_jsx("div", { className: "auto-form-field-wrapper", children: renderField(field) }, field.name))) }));
default: // single column
return (_jsx("div", { className: "auto-form-single-column", children: fields.map(field => (_jsx("div", { className: "auto-form-field-wrapper", children: renderField(field) }, field.name))) }));
}
};
return (_jsxs("form", { className: `auto-form ${className}`, onSubmit: handleSubmit, children: [_jsx("div", { className: "auto-form-content", children: renderFields() }), (onSubmit || onCancel) && (_jsxs("div", { className: "auto-form-actions", children: [onSubmit && (_jsx("button", { type: "submit", className: "auto-form-submit-btn", disabled: loading, children: loading ? 'Kaydediliyor...' : 'Kaydet' })), onCancel && (_jsx("button", { type: "button", className: "auto-form-cancel-btn", onClick: handleCancel, disabled: loading, children: "\u0130ptal" }))] }))] }));
}