UNPKG

zod-form-kit

Version:

UI-agnostic form generation library based on Zod schemas with extensible adapter pattern

78 lines (77 loc) 7.34 kB
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; // Radix UI field renderers function RadixStringField({ name, label, value = '', onChange, error, required, options = {}, className = '' }) { const inputType = getInputType(options.format); return (_jsxs("div", { className: `field string-field ${className}`, children: [_jsxs("label", { htmlFor: name, className: "field-label", children: [label, required && _jsx("span", { className: "required", children: "*" })] }), _jsx("input", { id: name, name: name, type: inputType, value: value, onChange: (e) => onChange(e.target.value), minLength: options.minLength, maxLength: options.maxLength, pattern: options.pattern?.source, className: `field-input ${error ? 'error' : ''}`, required: required, readOnly: options.readonly }), error && _jsx("span", { className: "field-error", children: error })] })); } function RadixNumberField({ name, label, value = 0, onChange, error, required, options = {}, className = '' }) { return (_jsxs("div", { className: `field number-field ${className}`, children: [_jsxs("label", { htmlFor: name, className: "field-label", children: [label, required && _jsx("span", { className: "required", children: "*" })] }), _jsx("input", { id: name, name: name, type: "number", value: value, onChange: (e) => onChange(Number(e.target.value)), min: options.min, max: options.max, step: options.step, className: `field-input ${error ? 'error' : ''}`, required: required, readOnly: options.readonly }), error && _jsx("span", { className: "field-error", children: error })] })); } function RadixBooleanField({ name, label, value = false, onChange, error, required, className = '' }) { return (_jsxs("div", { className: `field boolean-field ${className}`, children: [_jsxs("label", { className: "field-label", children: [_jsx("input", { type: "checkbox", name: name, checked: value, onChange: (e) => onChange(e.target.checked), required: required, className: error ? 'error' : '' }), label, required && _jsx("span", { className: "required", children: "*" })] }), error && _jsx("span", { className: "field-error", children: error })] })); } function RadixDateField({ name, label, value = null, onChange, error, required, className = '' }) { const dateValue = value ? value.toISOString().split('T')[0] : ''; return (_jsxs("div", { className: `field date-field ${className}`, children: [_jsxs("label", { htmlFor: name, className: "field-label", children: [label, required && _jsx("span", { className: "required", children: "*" })] }), _jsx("input", { id: name, name: name, type: "date", value: dateValue, onChange: (e) => onChange(e.target.value ? new Date(e.target.value) : null), className: `field-input ${error ? 'error' : ''}`, required: required }), error && _jsx("span", { className: "field-error", children: error })] })); } function RadixArrayField({ name: _name, label, value = [], onChange, error, required, itemSchema, errors: _errors, path, options = {}, className = '' }) { const addItem = () => { const newValue = [...value, getDefaultValue(itemSchema)]; onChange(path, newValue); }; const removeItem = (index) => { const newValue = value.filter((_, i) => i !== index); onChange(path, newValue); }; const canAddMore = !options.maxLength || value.length < options.maxLength; const canRemove = !options.minLength || value.length > options.minLength; return (_jsxs("div", { className: `field array-field ${className}`, children: [_jsxs("div", { className: "array-header", children: [_jsxs("label", { className: "field-label", children: [label, required && _jsx("span", { className: "required", children: "*" })] }), _jsx("button", { type: "button", onClick: addItem, disabled: !canAddMore, className: "add-button", children: "Add Item" })] }), _jsx("div", { className: "array-items", children: value.map((_item, index) => (_jsxs("div", { className: "array-item", children: [_jsx("div", { className: "item-content", children: _jsxs("span", { children: ["Item ", index + 1] }) }), canRemove && (_jsx("button", { type: "button", onClick: () => removeItem(index), className: "remove-button", children: "Remove" }))] }, index))) }), error && _jsx("span", { className: "field-error", children: error })] })); } function RadixObjectField({ name: _name, label, value: _value = {}, onChange: _onChange, error, required, properties, errors: _errors, path: _path, className = '' }) { return (_jsxs("div", { className: `field object-field ${className}`, children: [label && (_jsxs("div", { className: "object-label", children: [label, required && _jsx("span", { className: "required", children: "*" })] })), _jsx("div", { className: "object-properties", children: Object.entries(properties).map(([_key, _schema]) => { return (_jsxs("div", { className: "property-field", children: [_jsx("label", { className: "property-label", children: _key }), _jsxs("span", { children: ["Property: ", _key] })] }, _key)); }) }), error && _jsx("span", { className: "field-error", children: error })] })); } function RadixDiscriminatedUnionField({ name: _name, label, value = {}, onChange, error, required, discriminator, variants, errors: _errors, path, className = '' }) { const currentVariant = value[discriminator]; const variantOptions = Object.keys(variants); const handleVariantChange = (newVariant) => { const newValue = { [discriminator]: newVariant }; onChange(path, newValue); }; return (_jsxs("div", { className: `field discriminated-union-field ${className}`, children: [label && (_jsxs("div", { className: "union-label", children: [label, required && _jsx("span", { className: "required", children: "*" })] })), _jsxs("div", { className: "variant-selector", children: [_jsx("label", { className: "field-label", children: "Type" }), _jsxs("select", { value: currentVariant || '', onChange: (e) => handleVariantChange(e.target.value), className: "field-input", children: [_jsx("option", { value: "", children: "Select type..." }), variantOptions.map((variant) => (_jsx("option", { value: variant, children: variant }, variant)))] })] }), currentVariant && variants[currentVariant] && (_jsx("div", { className: "variant-fields", children: _jsxs("span", { children: ["Variant: ", currentVariant] }) })), error && _jsx("span", { className: "field-error", children: error })] })); } // Helper functions function getInputType(format) { switch (format) { case 'email': return 'email'; case 'url': return 'url'; default: return 'text'; } } function getDefaultValue(schema) { if (schema.defaultValue !== undefined) return schema.defaultValue; switch (schema.type) { case 'string': return ''; case 'number': return 0; case 'boolean': return false; case 'date': return new Date(); case 'array': return []; case 'object': return {}; default: return null; } } // Radix UI Adapter export const radixAdapter = { name: 'radix', components: { string: RadixStringField, number: RadixNumberField, boolean: RadixBooleanField, date: RadixDateField, array: RadixArrayField, object: RadixObjectField, discriminatedUnion: RadixDiscriminatedUnionField } };