UNPKG

zod-form-kit

Version:

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

117 lines (114 loc) 6.08 kB
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import { z } from 'zod'; import { ZodForm, registerSchemaPatternRenderer } from '../index'; // ============================================================================= // DEMO: Schema Pattern Registration for Upload Components // ============================================================================= // Define a Zod schema pattern for upload fields const uploadSchema = z.object({ upload: z.literal(true), url: z.string(), host: z.literal("cdn") }); // Custom Upload Component const CustomUploadComponent = ({ value, onChange, label, error, required, zodSchema: _zodSchema, parsedField: _parsedField }) => { const handleFileChange = (event) => { const file = event.target.files?.[0]; if (file) { // Simulate uploading and getting a URL const uploadedData = { upload: true, url: URL.createObjectURL(file), host: "cdn" }; onChange(uploadedData); } }; return (_jsxs("div", { className: "upload-field", children: [_jsxs("label", { htmlFor: "file-upload", children: [label, " ", required && _jsx("span", { style: { color: 'red' }, children: "*" })] }), _jsx("input", { id: "file-upload", type: "file", onChange: handleFileChange, accept: "image/*", style: { display: 'block', margin: '8px 0', padding: '8px', border: '2px dashed #ccc', borderRadius: '4px' } }), value?.url && (_jsxs("div", { style: { marginTop: '8px' }, children: [_jsxs("p", { children: ["Uploaded to: ", value.host] }), _jsx("img", { src: value.url, alt: "Preview", style: { maxWidth: '200px', maxHeight: '200px' } })] })), error && _jsx("div", { style: { color: 'red', fontSize: '12px' }, children: error })] })); }; // Register the pattern renderer registerSchemaPatternRenderer('upload-pattern', // unique ID uploadSchema, // Zod schema pattern to match CustomUploadComponent, // component to render 100 // high priority ); // Alternative: Register using a matcher function registerSchemaPatternRenderer('custom-upload-matcher', (zodSchema, _parsedField, _formValue) => { // Custom logic to determine if this schema should use our custom component return (zodSchema instanceof z.ZodObject && zodSchema.shape.upload instanceof z.ZodLiteral && zodSchema.shape.upload._def.value === true && zodSchema.shape.host instanceof z.ZodLiteral && zodSchema.shape.host._def.value === "cdn"); }, CustomUploadComponent, 90 // slightly lower priority than the schema-based matcher ); // ============================================================================= // DEMO: Schema Pattern for Special String Fields // ============================================================================= // Pattern for color picker fields const colorFieldMatcher = (zodSchema, parsedField) => { return (zodSchema instanceof z.ZodString && parsedField.options?.format === 'color'); }; const ColorPickerComponent = ({ value, onChange, label, error, required }) => { return (_jsxs("div", { className: "color-field", children: [_jsxs("label", { children: [label, " ", required && _jsx("span", { style: { color: 'red' }, children: "*" })] }), _jsx("input", { type: "color", value: value || '#000000', onChange: (e) => onChange(e.target.value), style: { display: 'block', margin: '8px 0', width: '60px', height: '40px', border: '1px solid #ccc', borderRadius: '4px' } }), error && _jsx("div", { style: { color: 'red', fontSize: '12px' }, children: error })] })); }; registerSchemaPatternRenderer('color-picker-pattern', colorFieldMatcher, ColorPickerComponent, 80); // ============================================================================= // DEMO FORM EXAMPLE // ============================================================================= // Example schema that uses the registered patterns const demoFormSchema = z.object({ title: z.string().min(1, 'Title is required'), profileImage: uploadSchema, coverImage: uploadSchema, themeColor: z.string().optional(), backgroundColor: z.string().optional(), description: z.string().optional() }); export const SchemaPatternDemo = () => { const handleSubmit = async (data) => { console.log('Form submitted with data:', data); alert('Form submitted! Check console for data.'); }; return (_jsxs("div", { style: { maxWidth: '600px', margin: '0 auto', padding: '20px' }, children: [_jsx("h1", { children: "Schema Pattern Registration Demo" }), _jsx("p", { children: "This demo shows how to register custom UI components for specific Zod schema patterns. The upload fields and color fields below use custom components that were registered to match specific schema patterns." }), _jsx(ZodForm, { schema: demoFormSchema, onSubmit: handleSubmit, defaultValues: { title: '', themeColor: '#3366cc', backgroundColor: '#ffffff' }, className: "demo-form" }), _jsxs("div", { style: { marginTop: '40px', padding: '20px', backgroundColor: '#f5f5f5' }, children: [_jsx("h3", { children: "Code Example:" }), _jsx("pre", { style: { fontSize: '12px', overflow: 'auto' }, children: `// Register custom component for upload pattern const uploadSchema = z.object({ upload: z.literal(true), url: z.string(), host: z.literal("cdn") }); registerSchemaPatternRenderer( 'upload-pattern', uploadSchema, CustomUploadComponent, 100 ); // Register custom component using matcher function registerSchemaPatternRenderer( 'color-picker-pattern', (zodSchema, parsedField) => ( zodSchema instanceof z.ZodString && parsedField.options?.format === 'color' ), ColorPickerComponent, 80 );` })] })] })); }; export default SchemaPatternDemo;