@forms.expert/sdk 0.4.7 → 0.4.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../vanilla/styles.ts","../../vanilla/renderer.ts","../../core/types.ts","../../core/api-client.ts","../../core/forms-sdk.ts","../../vanilla/widget.ts"],"sourcesContent":["import { FormStyling } from '../core/types';\n\nconst defaultStyling: FormStyling = {\n theme: 'light',\n primaryColor: '#3b82f6',\n backgroundColor: '#ffffff',\n textColor: '#1f2937',\n borderRadius: 'md',\n fontSize: 'md',\n buttonStyle: 'filled',\n labelPosition: 'top',\n};\n\nfunction getBorderRadius(radius: FormStyling['borderRadius']): string {\n switch (radius) {\n case 'none': return '0';\n case 'sm': return '0.125rem';\n case 'md': return '0.375rem';\n case 'lg': return '0.5rem';\n default: return '0.375rem';\n }\n}\n\nfunction getFieldBorderRadius(radius?: FormStyling['fieldBorderRadius']): string {\n switch (radius) {\n case 'none': return '0';\n case 'small': return '0.25rem';\n case 'medium': return '0.375rem';\n case 'large': return '0.75rem';\n case 'full': return '9999px';\n default: return '0.375rem';\n }\n}\n\nfunction getButtonRadius(radius?: FormStyling['buttonRadius']): string {\n switch (radius) {\n case 'none': return '0';\n case 'small': return '4px';\n case 'medium': return '8px';\n case 'large': return '12px';\n case 'full': return '9999px';\n default: return '8px';\n }\n}\n\nfunction getFontSize(size: FormStyling['fontSize']): string {\n switch (size) {\n case 'sm': case 'small': return '0.875rem';\n case 'md': case 'medium': return '1rem';\n case 'lg': case 'large': return '1.125rem';\n default: return '1rem';\n }\n}\n\nfunction getPlaceholderFontSize(size?: FormStyling['placeholderFontSize']): string {\n switch (size) {\n case 'small': return '0.75rem';\n case 'large': return '1rem';\n default: return '0.875rem';\n }\n}\n\nfunction getFieldSpacing(spacing?: FormStyling['fieldSpacing']): string {\n switch (spacing) {\n case 'compact': return '0.5rem';\n case 'relaxed': return '1.5rem';\n case 'spacious': return '2rem';\n default: return '1rem';\n }\n}\n\nfunction getFormPadding(padding?: FormStyling['formPadding']): string {\n switch (padding) {\n case 'none': return '0';\n case 'compact': return '1rem';\n case 'relaxed': return '2.5rem';\n case 'spacious': return '3.5rem';\n default: return '1.5rem';\n }\n}\n\nfunction getLabelSpacing(spacing?: FormStyling['labelSpacing']): string {\n switch (spacing) {\n case 'compact': return '0.125rem';\n case 'relaxed': return '0.75rem';\n default: return '0.25rem';\n }\n}\n\nfunction getFormWidth(width?: FormStyling['formWidth']): string {\n switch (width) {\n case 'narrow': return '28rem';\n case 'wide': return '48rem';\n case 'full': return '100%';\n default: return '36rem';\n }\n}\n\nfunction getButtonAlign(align?: FormStyling['buttonAlign']): string {\n switch (align) {\n case 'left': return 'flex-start';\n case 'right': return 'flex-end';\n default: return 'center';\n }\n}\n\nexport function generateFormStyles(styling: FormStyling = defaultStyling): string {\n const s = { ...defaultStyling, ...styling };\n const radius = getBorderRadius(s.borderRadius);\n const fieldRadius = getFieldBorderRadius(s.fieldBorderRadius);\n const btnRadius = getButtonRadius(s.buttonRadius);\n const fontSize = getFontSize(s.fontSize);\n const phFontSize = getPlaceholderFontSize(s.placeholderFontSize);\n const fieldSpacing = getFieldSpacing(s.fieldSpacing);\n const formPadding = getFormPadding(s.formPadding);\n const labelSpacing = getLabelSpacing(s.labelSpacing);\n const formWidth = getFormWidth(s.formWidth);\n const btnBgColor = s.primaryColor;\n const btnTextColor = s.buttonColor;\n const borderColor = s.fieldBorderColor || (s.theme === 'dark' ? '#4b5563' : '#d1d5db');\n const separatorColor = s.separatorColor || (s.theme === 'dark' ? '#4b5563' : '#d1d5db');\n // Normalize font family - support legacy single values by adding fallbacks\n // For SDK embedded forms, default to 'inherit' so the form uses the website's font\n const fontFamily = s.fontFamily \n ? (s.fontFamily.includes(',') ? s.fontFamily : `${s.fontFamily}, sans-serif`)\n : 'inherit';\n const btnAlign = getButtonAlign(s.buttonAlign);\n\n const btnSizeMap: Record<string, { px: string; py: string; fs: string }> = {\n small: { px: '0.75rem', py: '0.375rem', fs: '0.875rem' },\n medium: { px: '1.25rem', py: '0.625rem', fs: '1rem' },\n large: { px: '1.75rem', py: '0.875rem', fs: '1.125rem' },\n };\n const btnSize = btnSizeMap[s.buttonSize || 'medium'];\n const btnPx = s.buttonPaddingX != null ? `${s.buttonPaddingX}px` : btnSize.px;\n const btnPy = s.buttonPaddingY != null ? `${s.buttonPaddingY}px` : btnSize.py;\n const btnFs = s.buttonFontSize != null ? `${s.buttonFontSize}px` : btnSize.fs;\n const btnBg = s.buttonGradient || (s.buttonStyle === 'filled' ? btnBgColor : 'transparent');\n\n return `\n.forms-expert-wrapper {\n ${s.backgroundImageUrl ? `background-image: url(${s.backgroundImageUrl}); background-size: cover; background-position: center;` : ''}\n ${!s.backgroundImageUrl ? `background-color: ${s.backgroundColor};` : ''}\n position: relative;\n}\n\n.forms-expert-overlay {\n position: absolute;\n inset: 0;\n background-color: rgba(0,0,0,${s.backgroundOverlay || 0});\n pointer-events: none;\n}\n\n.forms-expert {\n font-family: ${fontFamily};\n font-size: ${fontSize};\n color: ${s.textColor};\n background-color: ${s.transparentBackground ? 'transparent' : s.backgroundColor};\n padding: ${formPadding};\n border-radius: ${radius};\n box-sizing: border-box;\n max-width: ${formWidth};\n width: 100%;\n margin: 0 auto;\n position: relative;\n}\n\n.forms-expert * {\n box-sizing: border-box;\n}\n\n.forms-expert-logo {\n display: block;\n max-height: 48px;\n margin-bottom: 1rem;\n}\n.forms-expert-logo-top-left { text-align: left; }\n.forms-expert-logo-top-center { text-align: center; }\n.forms-expert-logo-top-right { text-align: right; }\n.forms-expert-logo img { max-height: 48px; }\n\n.forms-expert-cover {\n width: 100%;\n max-height: 200px;\n object-fit: cover;\n border-radius: ${radius} ${radius} 0 0;\n margin-bottom: 1rem;\n}\n\n.forms-expert-group {\n margin-bottom: ${fieldSpacing};\n ${s.labelPosition === 'left' || s.fieldLayout === 'inline' ? 'display: flex; align-items: flex-start; gap: 1rem;' : ''}\n}\n\n.forms-expert-label {\n display: block;\n font-weight: 500;\n color: ${s.textColor};\n ${s.labelPosition === 'left' || s.fieldLayout === 'inline'\n ? `width: 33%; flex-shrink: 0; padding-top: 0.5rem; margin-bottom: 0;`\n : `margin-bottom: ${labelSpacing};`\n }\n}\n\n.forms-expert-required {\n color: #ef4444;\n margin-left: 0.25rem;\n}\n\n.forms-expert-input-wrapper {\n ${s.labelPosition === 'left' || s.fieldLayout === 'inline' ? 'flex: 1;' : ''}\n}\n\n.forms-expert-input,\n.forms-expert-textarea,\n.forms-expert-select {\n width: 100%;\n padding: ${s.fieldPaddingX != null || s.fieldPaddingY != null ? `${s.fieldPaddingY ?? 8}px ${s.fieldPaddingX ?? 12}px` : '0.5rem 0.75rem'};\n border: ${s.fieldBorderStyle === 'bottom' ? 'none' : `1px solid ${borderColor}`};\n ${s.fieldBorderStyle === 'bottom' ? `border-bottom: 1px solid ${borderColor};` : ''}\n border-radius: ${s.fieldBorderStyle === 'bottom' ? '0' : fieldRadius};\n font-size: ${fontSize};\n font-family: inherit;\n background-color: ${s.inputBackgroundColor || (s.theme === 'dark' ? '#374151' : '#ffffff')};\n color: ${s.textColor};\n transition: border-color 0.15s, box-shadow 0.15s;\n}\n\n.forms-expert-input::placeholder,\n.forms-expert-textarea::placeholder {\n font-size: ${phFontSize};${s.placeholderColor ? `\\n color: ${s.placeholderColor};` : ''}\n}\n\n.forms-expert-input:focus,\n.forms-expert-textarea:focus,\n.forms-expert-select:focus {\n outline: none !important;\n border-color: ${s.primaryColor} !important;\n box-shadow: 0 0 0 2px ${s.primaryColor}33 !important;\n -webkit-appearance: none;\n}\n\n.forms-expert-input.forms-expert-error,\n.forms-expert-textarea.forms-expert-error,\n.forms-expert-select.forms-expert-error {\n border-color: #ef4444;\n}\n\n.forms-expert-select-dropdown {\n position: absolute;\n top: 100%;\n left: 0;\n right: 0;\n z-index: 50;\n margin-top: 4px;\n background-color: ${s.inputBackgroundColor || (s.theme === 'dark' ? '#374151' : '#ffffff')};\n border: 1px solid ${borderColor};\n border-radius: ${fieldRadius};\n box-shadow: 0 4px 12px rgba(0,0,0,0.15);\n max-height: 200px;\n overflow-y: auto;\n}\n\n.forms-expert-select-option {\n padding: ${s.fieldPaddingX != null || s.fieldPaddingY != null ? `${s.fieldPaddingY ?? 8}px ${s.fieldPaddingX ?? 12}px` : '0.5rem 0.75rem'};\n cursor: pointer;\n font-size: ${fontSize};\n transition: background-color 0.1s;\n}\n\n.forms-expert-select-option:hover {\n background-color: ${s.primaryColor}15;\n}\n\n.forms-expert-select-option.active {\n background-color: ${s.primaryColor}20;\n}\n\n.forms-expert-textarea {\n min-height: 100px;\n resize: vertical;\n}\n\n.forms-expert-checkbox-group {\n display: flex;\n align-items: flex-start;\n gap: 0.5rem;\n margin-bottom: ${fieldSpacing};\n}\n\n.forms-expert-checkbox {\n width: 1rem;\n height: 1rem;\n margin-top: 0.125rem;\n flex-shrink: 0;\n accent-color: ${s.primaryColor};\n background-color: transparent;\n cursor: pointer;\n}\n\n.forms-expert-file-wrapper {\n position: relative;\n}\n\n.forms-expert-dropzone {\n position: relative;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 0.5rem;\n border: 2px dashed ${borderColor};\n border-radius: ${fieldRadius};\n padding: 1.5rem;\n cursor: pointer;\n transition: border-color 0.15s, background-color 0.15s;\n}\n\n.forms-expert-dropzone:hover {\n border-color: ${s.primaryColor}80;\n background-color: ${s.theme === 'dark' ? 'rgba(255,255,255,0.05)' : 'rgba(0,0,0,0.02)'};\n}\n\n.forms-expert-file {\n width: 100%;\n padding: 0.5rem 0.75rem;\n border: ${s.fieldBorderStyle === 'bottom' ? 'none' : `1px solid ${borderColor}`};\n ${s.fieldBorderStyle === 'bottom' ? `border-bottom: 1px solid ${borderColor};` : ''}\n border-radius: ${s.fieldBorderStyle === 'bottom' ? '0' : fieldRadius};\n font-size: ${fontSize};\n background-color: ${s.inputBackgroundColor || (s.theme === 'dark' ? '#374151' : '#ffffff')};\n cursor: pointer;\n}\n\n.forms-expert-error-message {\n color: ${s.errorColor || '#ef4444'};\n font-size: 0.875rem;\n margin-top: 0.25rem;\n}\n\n.forms-expert-divider {\n border: none;\n border-top: 1px solid ${separatorColor};\n margin: ${fieldSpacing} 0;\n}\n\n.forms-expert-button-wrapper {\n display: flex;\n justify-content: ${btnAlign};\n margin-top: 1rem;\n gap: 0.5rem;\n flex-wrap: wrap;\n}\n\n.forms-expert-button {\n ${s.buttonFullWidth ? 'width: 100%;' : (s.buttonAlign ? '' : 'width: 100%;')}\n padding: ${btnPy} ${btnPx};\n font-weight: 500;\n font-size: ${btnFs};\n font-family: inherit;\n border-radius: ${btnRadius};\n cursor: pointer;\n transition: opacity 0.2s, transform 0.1s;\n max-width: 100%;\n box-sizing: border-box;\n flex-shrink: 1;\n min-width: 0;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n ${s.buttonStyle === 'filled' \n ? `background: ${btnBg}; color: ${btnTextColor || 'white'}; border: none;`\n : `background: transparent; color: ${btnBgColor}; border: 2px solid ${btnBgColor};`\n }\n}\n\n.forms-expert-button:hover {\n filter: brightness(0.9);\n}\n\n.forms-expert-button:active {\n transform: scale(0.98);\n filter: brightness(0.85);\n}\n\n.forms-expert-button:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n transform: none;\n}\n\n.forms-expert-button-loading {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.5rem;\n}\n\n.forms-expert-spinner {\n width: 1rem;\n height: 1rem;\n border: 2px solid transparent;\n border-top-color: currentColor;\n border-radius: 50%;\n animation: forms-expert-spin 0.6s linear infinite;\n}\n\n@keyframes forms-expert-spin {\n to { transform: rotate(360deg); }\n}\n\n.forms-expert-honeypot {\n position: absolute;\n left: -9999px;\n opacity: 0;\n}\n\n.forms-expert-success {\n text-align: center;\n padding: 2rem;\n color: ${s.textColor};\n}\n\n.forms-expert-success-icon {\n width: 3rem;\n height: 3rem;\n margin: 0 auto 1rem;\n color: ${s.successColor || '#22c55e'};\n}\n\n.forms-expert-success-message {\n font-size: 1.125rem;\n font-weight: 500;\n margin-bottom: 0.5rem;\n}\n\n.forms-expert-branding {\n text-align: center;\n margin-top: 1rem;\n padding-top: 0.75rem;\n border-top: 1px solid ${separatorColor};\n}\n\n.forms-expert-branding a {\n color: ${s.theme === 'dark' ? '#9ca3af' : '#6b7280'};\n text-decoration: none;\n font-size: 0.75rem;\n}\n\n.forms-expert-branding a:hover {\n text-decoration: underline;\n}\n\n.forms-expert-secondary-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n padding: 0.625rem 1.25rem;\n font-weight: 500;\n font-size: ${fontSize};\n font-family: inherit;\n border-radius: ${btnRadius};\n cursor: pointer;\n transition: opacity 0.2s;\n text-decoration: none;\n max-width: 100%;\n box-sizing: border-box;\n flex-shrink: 1;\n min-width: 0;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.forms-expert-secondary-btn:hover { filter: brightness(0.9); }\n.forms-expert-secondary-btn:active { filter: brightness(0.85); }\n\n.forms-expert-secondary-below {\n display: flex;\n margin-top: 0.5rem;\n}\n\n/* Rating stars */\n.forms-expert-rating { display: flex; gap: 0.25rem; }\n.forms-expert-rating-star {\n width: 2rem; height: 2rem; cursor: pointer; border: none;\n background: none; padding: 0; font-size: 1.5rem; color: ${s.theme === 'dark' ? '#4b5563' : '#d1d5db'};\n transition: color 0.15s;\n}\n.forms-expert-rating-star.active { color: #f59e0b; }\n\n/* Scale buttons */\n.forms-expert-scale { display: flex; gap: 0.25rem; flex-wrap: wrap; }\n.forms-expert-scale-labels { display: flex; justify-content: space-between; font-size: 0.75rem; color: ${s.theme === 'dark' ? '#9ca3af' : '#6b7280'}; margin-top: 0.25rem; }\n.forms-expert-scale-btn {\n min-width: 2.25rem; height: 2.25rem; border-radius: ${radius}; cursor: pointer;\n border: 1px solid ${s.theme === 'dark' ? '#4b5563' : '#d1d5db'};\n background: ${s.theme === 'dark' ? '#374151' : '#ffffff'}; color: ${s.textColor};\n font-size: 0.875rem; transition: all 0.15s;\n}\n.forms-expert-scale-btn.active {\n background-color: ${s.primaryColor}; color: white; border-color: ${s.primaryColor};\n}\n\n/* Radio & multiselect groups */\n.forms-expert-radio-group,\n.forms-expert-multiselect-group {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n width: 100%;\n padding: ${s.fieldPaddingX != null || s.fieldPaddingY != null ? `${s.fieldPaddingY ?? 8}px ${s.fieldPaddingX ?? 12}px` : '0.5rem 0.75rem'};\n border: ${s.fieldBorderStyle === 'bottom' ? 'none' : `1px solid ${borderColor}`};\n ${s.fieldBorderStyle === 'bottom' ? `border-bottom: 1px solid ${borderColor};` : ''}\n border-radius: ${s.fieldBorderStyle === 'bottom' ? '0' : fieldRadius};\n background-color: ${s.inputBackgroundColor || (s.theme === 'dark' ? '#374151' : '#ffffff')};\n box-sizing: border-box;\n}\n.forms-expert-radio-item,\n.forms-expert-multiselect-item { display: flex; align-items: center; gap: 0.5rem; cursor: pointer; }\n.forms-expert-radio-item input,\n.forms-expert-multiselect-item input { accent-color: ${s.primaryColor}; }\n\n/* Slider */\n.forms-expert-slider { width: 100%; accent-color: ${s.primaryColor}; }\n.forms-expert-slider-value { text-align: center; font-size: 0.875rem; margin-top: 0.25rem; }\n\n/* Image choice */\n.forms-expert-image-choice { display: flex; flex-wrap: wrap; gap: 0.5rem; }\n.forms-expert-image-choice-item {\n border: 2px solid ${s.theme === 'dark' ? '#4b5563' : '#d1d5db'}; border-radius: ${radius};\n padding: 0.5rem; cursor: pointer; text-align: center; transition: border-color 0.15s;\n}\n.forms-expert-image-choice-item.active { border-color: ${s.primaryColor}; }\n.forms-expert-image-choice-item img { max-width: 80px; max-height: 80px; object-fit: cover; border-radius: ${radius}; }\n\n/* Responsive button scaling */\n@media (max-width: 480px) {\n .forms-expert-button,\n .forms-expert-secondary-btn {\n padding-left: max(0.5rem, min(${btnPx}, 3vw));\n padding-right: max(0.5rem, min(${btnPx}, 3vw));\n font-size: max(0.75rem, min(${btnFs}, 3.5vw));\n }\n}\n\n${s.customCss || ''}\n`.trim();\n}\n","import { FormField, FormSchema, FormStyling, SecondaryButton, ValidationError } from '../core/types';\n\n/**\n * Escape HTML special characters\n */\nfunction escapeHtml(text: string): string {\n const div = document.createElement('div');\n div.textContent = text;\n return div.innerHTML;\n}\n\n/**\n * Layout field types that don't capture data\n */\nconst LAYOUT_TYPES = new Set(['heading', 'divider', 'paragraph']);\n\n/**\n * Heading size map\n */\nfunction getHeadingSizePx(size?: string): string {\n switch (size) {\n case 'small': return '18px';\n case 'large': return '30px';\n case 'extra-large': return '36px';\n default: return '24px';\n }\n}\n\n/**\n * Paragraph size map\n */\nfunction getParagraphSizePx(size?: string): string {\n switch (size) {\n case 'small': return '14px';\n case 'large': return '18px';\n default: return '16px';\n }\n}\n\n/**\n * Helper to add custom class names to elements\n */\nfunction addCustomClass(baseClass: string, customClass?: string): string {\n return customClass ? `${baseClass} ${customClass}` : baseClass;\n}\n\nfunction normalizeOpts(options: unknown[]): { value: string; label: string }[] {\n return options.map((o) => typeof o === 'string' ? { value: o, label: o } : o as { value: string; label: string });\n}\n\nfunction getWidthPercent(width?: string): string | undefined {\n switch (width) {\n case '1/4': return '25%';\n case '1/3': return '33.333%';\n case '1/2': return '50%';\n case '2/3': return '66.666%';\n case '3/4': return '75%';\n case 'full': return '100%';\n default: return undefined;\n }\n}\n\n/**\n * Create a form field element\n */\nexport function renderField(\n field: FormField,\n value: unknown,\n error?: string,\n styling?: Partial<FormStyling>\n): HTMLElement {\n const group = document.createElement('div');\n\n // Layout fields\n if (field.type === 'heading') {\n group.className = 'forms-expert-group';\n const h = document.createElement('h3');\n h.className = 'forms-expert-heading';\n h.style.fontSize = getHeadingSizePx(styling?.headingSize);\n h.textContent = field.label || '';\n group.appendChild(h);\n if (field.content) {\n const p = document.createElement('p');\n p.className = 'forms-expert-heading-subtitle';\n p.textContent = field.content;\n group.appendChild(p);\n }\n return group;\n }\n\n if (field.type === 'divider') {\n const hr = document.createElement('hr');\n hr.className = 'forms-expert-divider';\n return hr;\n }\n\n if (field.type === 'paragraph') {\n group.className = 'forms-expert-group';\n const pFontSize = field.paragraphFontSize\n ? `${field.paragraphFontSize}px`\n : getParagraphSizePx(styling?.paragraphSize);\n if (field.label) {\n const p = document.createElement('p');\n p.className = 'forms-expert-paragraph-label';\n p.style.fontSize = pFontSize;\n p.textContent = field.label;\n group.appendChild(p);\n }\n if (field.content) {\n const div = document.createElement('div');\n div.className = 'forms-expert-paragraph';\n div.style.fontSize = pFontSize;\n div.innerHTML = field.content;\n group.appendChild(div);\n }\n return group;\n }\n\n // Hidden field\n if (field.type === 'hidden') {\n const input = document.createElement('input');\n input.type = 'hidden';\n input.name = field.name;\n input.value = String(field.defaultValue ?? value ?? '');\n group.appendChild(input);\n group.style.display = 'none';\n return group;\n }\n\n // Checkbox / toggle / consent\n if (field.type === 'checkbox' || field.type === 'toggle' || field.type === 'consent') {\n group.className = 'forms-expert-checkbox-group';\n \n const input = document.createElement('input');\n input.type = 'checkbox';\n input.id = `mira-field-${field.name}`;\n input.name = field.name;\n input.className = 'forms-expert-checkbox';\n input.checked = Boolean(value);\n if (field.required) input.required = true;\n \n const wrapper = document.createElement('div');\n\n const label = document.createElement('label');\n label.htmlFor = input.id;\n label.style.cursor = 'pointer';\n if (field.type === 'consent' && field.consentFontSize) {\n label.style.fontSize = `${field.consentFontSize}px`;\n }\n const text = field.type === 'consent' ? (field.consentText || field.label || field.name) : (field.label || field.name);\n label.innerHTML = `${escapeHtml(text)}${field.required ? '<span class=\"forms-expert-required\">*</span>' : ''}`;\n wrapper.appendChild(label);\n\n if (field.type === 'consent' && field.consentUrl) {\n const link = document.createElement('a');\n link.href = field.consentUrl;\n link.target = '_blank';\n link.rel = 'noopener noreferrer';\n link.textContent = 'View policy';\n link.className = 'forms-expert-consent-link';\n wrapper.appendChild(link);\n }\n \n group.appendChild(input);\n group.appendChild(wrapper);\n\n if (error) {\n const errorEl = document.createElement('div');\n errorEl.className = 'forms-expert-error-message';\n errorEl.textContent = error;\n group.appendChild(errorEl);\n }\n return group;\n }\n\n // All other fields\n group.className = 'forms-expert-group';\n \n // Label\n if (field.label) {\n const label = document.createElement('label');\n label.className = `forms-expert-label${styling?.labelClassName ? ' ' + styling.labelClassName : ''}`;\n label.htmlFor = `mira-field-${field.name}`;\n label.innerHTML = `${escapeHtml(field.label)}${field.required ? '<span class=\"forms-expert-required\">*</span>' : ''}`;\n group.appendChild(label);\n }\n \n // Input wrapper\n const wrapper = document.createElement('div');\n wrapper.className = 'forms-expert-input-wrapper';\n \n let input: HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement;\n \n switch (field.type) {\n case 'textarea':\n case 'richText':\n input = document.createElement('textarea');\n input.className = addCustomClass('forms-expert-textarea', styling?.fieldClassName);\n input.value = String(value || '');\n if (field.maxLength) input.maxLength = field.maxLength;\n break;\n \n case 'select':\n case 'dropdown': {\n const selectWrapper = document.createElement('div');\n selectWrapper.style.position = 'relative';\n selectWrapper.style.width = '100%';\n if (styling?.fieldClassName) selectWrapper.className = styling.fieldClassName;\n\n const selectBtn = document.createElement('button');\n selectBtn.type = 'button';\n selectBtn.className = 'forms-expert-select';\n selectBtn.style.display = 'flex';\n selectBtn.style.alignItems = 'center';\n selectBtn.style.justifyContent = 'space-between';\n selectBtn.style.cursor = 'pointer';\n selectBtn.style.textAlign = 'left';\n selectBtn.style.width = '100%';\n\n const opts = normalizeOpts(field.options || []);\n const selectedOpt = opts.find((o) => o.value === String(value || ''));\n\n const labelSpan = document.createElement('span');\n labelSpan.textContent = selectedOpt?.label || field.placeholder || 'Select an option...';\n if (!selectedOpt && styling?.placeholderColor) labelSpan.style.color = styling.placeholderColor;\n selectBtn.appendChild(labelSpan);\n\n const arrow = document.createElement('span');\n arrow.innerHTML = '<svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\"><path d=\"M3 4.5L6 7.5L9 4.5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>';\n arrow.style.flexShrink = '0';\n arrow.style.opacity = '0.5';\n selectBtn.appendChild(arrow);\n\n const dropdown = document.createElement('div');\n dropdown.className = 'forms-expert-select-dropdown';\n dropdown.style.display = 'none';\n\n opts.forEach((opt) => {\n const item = document.createElement('div');\n item.className = 'forms-expert-select-option';\n item.textContent = opt.label;\n if (String(value || '') === opt.value) item.classList.add('active');\n item.addEventListener('mousedown', (e) => {\n e.preventDefault();\n hiddenInput.value = opt.value;\n labelSpan.textContent = opt.label;\n if (styling?.placeholderColor) labelSpan.style.color = '';\n dropdown.querySelectorAll('.forms-expert-select-option').forEach((el) => el.classList.remove('active'));\n item.classList.add('active');\n dropdown.style.display = 'none';\n hiddenInput.dispatchEvent(new Event('input', { bubbles: true }));\n });\n dropdown.appendChild(item);\n });\n\n selectBtn.addEventListener('click', () => {\n dropdown.style.display = dropdown.style.display === 'none' ? 'block' : 'none';\n });\n selectBtn.addEventListener('blur', () => {\n setTimeout(() => { dropdown.style.display = 'none'; }, 150);\n });\n\n const hiddenInput = document.createElement('input');\n hiddenInput.type = 'hidden';\n hiddenInput.name = field.name;\n hiddenInput.value = String(value || '');\n if (field.required) hiddenInput.required = true;\n\n selectWrapper.appendChild(selectBtn);\n selectWrapper.appendChild(dropdown);\n selectWrapper.appendChild(hiddenInput);\n\n wrapper.appendChild(selectWrapper);\n if (error) {\n const errorEl = document.createElement('div');\n errorEl.className = 'forms-expert-error-message';\n errorEl.textContent = error;\n wrapper.appendChild(errorEl);\n }\n group.appendChild(wrapper);\n return group;\n }\n\n case 'radio': {\n // Render as radio group\n const radioGroup = document.createElement('div');\n radioGroup.className = 'forms-expert-radio-group';\n const opts = (field.options || []) as string[];\n opts.forEach((opt) => {\n const radioWrapper = document.createElement('label');\n radioWrapper.className = 'forms-expert-radio-item';\n const radioInput = document.createElement('input');\n radioInput.type = 'radio';\n radioInput.name = field.name;\n radioInput.value = opt;\n radioInput.checked = value === opt;\n radioWrapper.appendChild(radioInput);\n radioWrapper.appendChild(document.createTextNode(` ${opt}`));\n radioGroup.appendChild(radioWrapper);\n });\n wrapper.appendChild(radioGroup);\n if (error) {\n const errorEl = document.createElement('div');\n errorEl.className = 'forms-expert-error-message';\n errorEl.textContent = error;\n wrapper.appendChild(errorEl);\n }\n group.appendChild(wrapper);\n return group;\n }\n\n case 'multiselect': {\n const checkGroup = document.createElement('div');\n checkGroup.className = 'forms-expert-multiselect-group';\n const selected = (value as string[]) || [];\n const opts = (field.options || []) as string[];\n opts.forEach((opt) => {\n const checkWrapper = document.createElement('label');\n checkWrapper.className = 'forms-expert-checkbox-item';\n const checkInput = document.createElement('input');\n checkInput.type = 'checkbox';\n checkInput.name = field.name;\n checkInput.value = opt;\n checkInput.checked = selected.includes(opt);\n checkWrapper.appendChild(checkInput);\n checkWrapper.appendChild(document.createTextNode(` ${opt}`));\n checkGroup.appendChild(checkWrapper);\n });\n wrapper.appendChild(checkGroup);\n if (error) {\n const errorEl = document.createElement('div');\n errorEl.className = 'forms-expert-error-message';\n errorEl.textContent = error;\n wrapper.appendChild(errorEl);\n }\n group.appendChild(wrapper);\n return group;\n }\n\n case 'rating': {\n const ratingContainer = document.createElement('div');\n ratingContainer.className = 'forms-expert-rating';\n const max = field.ratingMax || 5;\n const current = (value as number) || 0;\n for (let i = 1; i <= max; i++) {\n const star = document.createElement('button');\n star.type = 'button';\n star.className = `forms-expert-rating-star ${i <= current ? 'active' : ''}`;\n star.textContent = '★';\n star.dataset.value = String(i);\n ratingContainer.appendChild(star);\n }\n wrapper.appendChild(ratingContainer);\n if (error) {\n const errorEl = document.createElement('div');\n errorEl.className = 'forms-expert-error-message';\n errorEl.textContent = error;\n wrapper.appendChild(errorEl);\n }\n group.appendChild(wrapper);\n return group;\n }\n\n case 'scale':\n case 'opinionScale': {\n const scaleContainer = document.createElement('div');\n scaleContainer.className = 'forms-expert-scale';\n const min = field.min ?? (field.type === 'opinionScale' ? 0 : 1);\n const max = field.max ?? (field.type === 'opinionScale' ? 10 : 5);\n const current = value as number | undefined;\n for (let i = min; i <= max; i++) {\n const btn = document.createElement('button');\n btn.type = 'button';\n btn.className = `forms-expert-scale-btn ${current === i ? 'active' : ''}`;\n btn.textContent = String(i);\n btn.dataset.value = String(i);\n scaleContainer.appendChild(btn);\n }\n wrapper.appendChild(scaleContainer);\n if (field.lowLabel || field.highLabel) {\n const labels = document.createElement('div');\n labels.className = 'forms-expert-scale-labels';\n labels.innerHTML = `<span>${escapeHtml(field.lowLabel || '')}</span><span>${escapeHtml(field.highLabel || '')}</span>`;\n wrapper.appendChild(labels);\n }\n if (error) {\n const errorEl = document.createElement('div');\n errorEl.className = 'forms-expert-error-message';\n errorEl.textContent = error;\n wrapper.appendChild(errorEl);\n }\n group.appendChild(wrapper);\n return group;\n }\n\n case 'slider': {\n input = document.createElement('input');\n input.type = 'range';\n input.className = 'forms-expert-slider';\n input.min = String(field.min ?? 0);\n input.max = String(field.max ?? 100);\n input.step = String(field.step ?? 1);\n input.value = String(value ?? field.min ?? 0);\n break;\n }\n\n case 'file': {\n const borderColor = styling?.theme === 'dark' ? '#4b5563' : '#d1d5db';\n const mutedColor = styling?.theme === 'dark' ? '#9ca3af' : '#6b7280';\n const primaryColor = styling?.primaryColor || '#3b82f6';\n\n const dropzone = document.createElement('label');\n dropzone.htmlFor = `mira-field-${field.name}`;\n dropzone.className = 'forms-expert-dropzone';\n\n const fileInput = document.createElement('input');\n fileInput.id = `mira-field-${field.name}`;\n fileInput.name = field.name;\n fileInput.type = 'file';\n fileInput.style.cssText = 'position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0';\n if (field.allowedMimeTypes?.length) fileInput.accept = field.allowedMimeTypes.join(',');\n if (field.multiple) fileInput.multiple = true;\n dropzone.appendChild(fileInput);\n\n const icon = document.createElement('div');\n icon.innerHTML = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"32\" height=\"32\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"${mutedColor}\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\"/><polyline points=\"17 8 12 3 7 8\"/><line x1=\"12\" x2=\"12\" y1=\"3\" y2=\"15\"/></svg>`;\n dropzone.appendChild(icon);\n\n const text = document.createElement('span');\n text.style.cssText = 'font-size:0.875rem;font-weight:500';\n text.textContent = 'Drag & drop a file here, or click to browse';\n dropzone.appendChild(text);\n\n if (field.allowedMimeTypes?.length) {\n const types = document.createElement('span');\n types.style.cssText = `font-size:0.75rem;color:${mutedColor}`;\n types.textContent = field.allowedMimeTypes.join(', ');\n dropzone.appendChild(types);\n }\n if (field.maxFileSize) {\n const sizeInfo = document.createElement('span');\n sizeInfo.style.cssText = `font-size:0.75rem;color:${mutedColor}`;\n const s = field.maxFileSize;\n sizeInfo.textContent = `Max size: ${s < 1048576 ? `${(s / 1024).toFixed(0)} KB` : `${(s / 1048576).toFixed(0)} MB`}`;\n dropzone.appendChild(sizeInfo);\n }\n\n dropzone.addEventListener('dragover', (e) => { e.preventDefault(); dropzone.style.borderColor = primaryColor; dropzone.style.backgroundColor = styling?.theme === 'dark' ? 'rgba(255,255,255,0.08)' : 'rgba(0,0,0,0.04)'; });\n dropzone.addEventListener('dragleave', () => { dropzone.style.borderColor = borderColor; dropzone.style.backgroundColor = 'transparent'; });\n dropzone.addEventListener('drop', (e) => {\n e.preventDefault();\n dropzone.style.borderColor = borderColor;\n dropzone.style.backgroundColor = 'transparent';\n });\n\n group.appendChild(dropzone);\n if (error) {\n const errorEl = document.createElement('div');\n errorEl.className = 'forms-expert-error-message';\n errorEl.textContent = error;\n group.appendChild(errorEl);\n }\n return group;\n }\n\n case 'currency': {\n input = document.createElement('input');\n input.type = 'number';\n input.className = addCustomClass('forms-expert-input', styling?.fieldClassName);\n input.value = String(value ?? '');\n if (field.min !== undefined) input.min = String(field.min);\n if (field.max !== undefined) input.max = String(field.max);\n input.step = String(field.step || 0.01);\n break;\n }\n\n case 'phone':\n input = document.createElement('input');\n input.type = 'tel';\n input.className = addCustomClass('forms-expert-input', styling?.fieldClassName);\n input.value = String(value || '');\n break;\n\n case 'url':\n input = document.createElement('input');\n input.type = 'url';\n input.className = addCustomClass('forms-expert-input', styling?.fieldClassName);\n input.value = String(value || '');\n break;\n\n case 'password':\n input = document.createElement('input');\n input.type = 'password';\n input.className = addCustomClass('forms-expert-input', styling?.fieldClassName);\n input.value = String(value || '');\n break;\n\n case 'time':\n input = document.createElement('input');\n input.type = 'time';\n input.className = addCustomClass('forms-expert-input', styling?.fieldClassName);\n input.value = String(value || '');\n break;\n\n case 'datetime':\n input = document.createElement('input');\n input.type = 'datetime-local';\n input.className = addCustomClass('forms-expert-input', styling?.fieldClassName);\n input.value = String(value || '');\n break;\n\n case 'colorPicker':\n input = document.createElement('input');\n input.type = 'color';\n input.className = 'forms-expert-color';\n input.value = String(value || '#000000');\n break;\n\n case 'dateRange': {\n // Two date inputs\n const rangeContainer = document.createElement('div');\n rangeContainer.className = 'forms-expert-date-range';\n const range = (value as { start?: string; end?: string }) || {};\n const startInput = document.createElement('input');\n startInput.type = 'date';\n startInput.className = addCustomClass('forms-expert-input', styling?.fieldClassName);\n startInput.name = `${field.name}.start`;\n startInput.value = range.start || '';\n const endInput = document.createElement('input');\n endInput.type = 'date';\n endInput.className = addCustomClass('forms-expert-input', styling?.fieldClassName);\n endInput.name = `${field.name}.end`;\n endInput.value = range.end || '';\n rangeContainer.appendChild(startInput);\n rangeContainer.appendChild(endInput);\n wrapper.appendChild(rangeContainer);\n if (error) {\n const errorEl = document.createElement('div');\n errorEl.className = 'forms-expert-error-message';\n errorEl.textContent = error;\n wrapper.appendChild(errorEl);\n }\n group.appendChild(wrapper);\n return group;\n }\n\n case 'address': {\n const addrContainer = document.createElement('div');\n addrContainer.className = 'forms-expert-address';\n const addrFields = field.addressFields || ['street', 'city', 'state', 'zip', 'country'];\n const addr = (value as Record<string, string>) || {};\n const labels: Record<string, string> = { street: 'Street', street2: 'Street Line 2', city: 'City', state: 'State', zip: 'ZIP', country: 'Country' };\n addrFields.forEach((af) => {\n const inp = document.createElement('input');\n inp.type = 'text';\n inp.className = addCustomClass('forms-expert-input', styling?.fieldClassName);\n inp.name = `${field.name}.${af}`;\n inp.placeholder = labels[af] || af;\n inp.value = addr[af] || '';\n addrContainer.appendChild(inp);\n });\n wrapper.appendChild(addrContainer);\n if (error) {\n const errorEl = document.createElement('div');\n errorEl.className = 'forms-expert-error-message';\n errorEl.textContent = error;\n wrapper.appendChild(errorEl);\n }\n group.appendChild(wrapper);\n return group;\n }\n\n case 'name': {\n const nameContainer = document.createElement('div');\n nameContainer.className = 'forms-expert-name';\n const nameFields = field.nameFields || ['first', 'last'];\n const nameVal = (value as Record<string, string>) || {};\n const labels: Record<string, string> = { prefix: 'Prefix', first: 'First Name', middle: 'Middle', last: 'Last Name', suffix: 'Suffix' };\n nameFields.forEach((nf) => {\n const inp = document.createElement('input');\n inp.type = 'text';\n inp.className = addCustomClass('forms-expert-input', styling?.fieldClassName);\n inp.name = `${field.name}.${nf}`;\n inp.placeholder = labels[nf] || nf;\n inp.value = nameVal[nf] || '';\n nameContainer.appendChild(inp);\n });\n wrapper.appendChild(nameContainer);\n if (error) {\n const errorEl = document.createElement('div');\n errorEl.className = 'forms-expert-error-message';\n errorEl.textContent = error;\n wrapper.appendChild(errorEl);\n }\n group.appendChild(wrapper);\n return group;\n }\n\n case 'imageChoice': {\n const imgContainer = document.createElement('div');\n imgContainer.className = 'forms-expert-image-choice';\n const opts = (field.options || []) as Array<{ label: string; value: string; imageUrl?: string }>;\n const selected = value as string;\n opts.forEach((opt) => {\n const card = document.createElement('button');\n card.type = 'button';\n card.className = `forms-expert-image-choice-item ${selected === opt.value ? 'active' : ''}`;\n card.dataset.value = opt.value;\n if (opt.imageUrl) {\n const img = document.createElement('img');\n img.src = opt.imageUrl;\n img.alt = opt.label;\n card.appendChild(img);\n }\n const lbl = document.createElement('span');\n lbl.textContent = opt.label;\n card.appendChild(lbl);\n imgContainer.appendChild(card);\n });\n wrapper.appendChild(imgContainer);\n if (error) {\n const errorEl = document.createElement('div');\n errorEl.className = 'forms-expert-error-message';\n errorEl.textContent = error;\n wrapper.appendChild(errorEl);\n }\n group.appendChild(wrapper);\n return group;\n }\n\n case 'ranking': {\n const rankContainer = document.createElement('div');\n rankContainer.className = 'forms-expert-ranking';\n const opts = (field.options || []) as string[];\n const ranked = (value as string[]) || [...opts];\n ranked.forEach((item, i) => {\n const row = document.createElement('div');\n row.className = 'forms-expert-ranking-item';\n row.textContent = `${i + 1}. ${item}`;\n row.dataset.value = item;\n rankContainer.appendChild(row);\n });\n wrapper.appendChild(rankContainer);\n if (error) {\n const errorEl = document.createElement('div');\n errorEl.className = 'forms-expert-error-message';\n errorEl.textContent = error;\n wrapper.appendChild(errorEl);\n }\n group.appendChild(wrapper);\n return group;\n }\n\n case 'location': {\n const locContainer = document.createElement('div');\n locContainer.className = 'forms-expert-location';\n const loc = (value as { lat?: number; lng?: number; address?: string }) || {};\n const addrInput = document.createElement('input');\n addrInput.type = 'text';\n addrInput.className = addCustomClass('forms-expert-input', styling?.fieldClassName);\n addrInput.name = `${field.name}.address`;\n addrInput.placeholder = 'Address';\n addrInput.value = loc.address || '';\n locContainer.appendChild(addrInput);\n const coordRow = document.createElement('div');\n coordRow.className = 'forms-expert-location-coords';\n const latInput = document.createElement('input');\n latInput.type = 'number';\n latInput.className = addCustomClass('forms-expert-input', styling?.fieldClassName);\n latInput.name = `${field.name}.lat`;\n latInput.placeholder = 'Latitude';\n latInput.step = 'any';\n latInput.value = loc.lat !== undefined ? String(loc.lat) : '';\n const lngInput = document.createElement('input');\n lngInput.type = 'number';\n lngInput.className = addCustomClass('forms-expert-input', styling?.fieldClassName);\n lngInput.name = `${field.name}.lng`;\n lngInput.placeholder = 'Longitude';\n lngInput.step = 'any';\n lngInput.value = loc.lng !== undefined ? String(loc.lng) : '';\n coordRow.appendChild(latInput);\n coordRow.appendChild(lngInput);\n locContainer.appendChild(coordRow);\n wrapper.appendChild(locContainer);\n if (error) {\n const errorEl = document.createElement('div');\n errorEl.className = 'forms-expert-error-message';\n errorEl.textContent = error;\n wrapper.appendChild(errorEl);\n }\n group.appendChild(wrapper);\n return group;\n }\n\n default:\n input = document.createElement('input');\n input.type = field.type === 'email' ? 'email' : field.type === 'number' ? 'number' : field.type === 'date' ? 'date' : 'text';\n input.className = addCustomClass('forms-expert-input', styling?.fieldClassName);\n input.value = String(value || '');\n if (field.type === 'number') {\n if (field.min !== undefined) input.min = String(field.min);\n if (field.max !== undefined) input.max = String(field.max);\n if (field.step !== undefined) input.step = String(field.step);\n }\n break;\n }\n \n input!.id = `mira-field-${field.name}`;\n input!.name = field.name;\n if (field.placeholder && 'placeholder' in input!) {\n (input as HTMLInputElement | HTMLTextAreaElement).placeholder = field.placeholder;\n }\n if (field.required) input!.required = true;\n \n if (error) {\n input!.classList.add('forms-expert-error');\n }\n \n wrapper.appendChild(input!);\n \n // Error message\n if (error) {\n const errorEl = document.createElement('div');\n errorEl.className = 'forms-expert-error-message';\n errorEl.textContent = error;\n wrapper.appendChild(errorEl);\n }\n \n group.appendChild(wrapper);\n \n return group;\n}\n\n/**\n * Render the entire form\n */\nexport function renderForm(\n schema: FormSchema,\n values: Record<string, unknown> = {},\n errors: Record<string, string> = {},\n options: {\n honeypot?: boolean;\n showBranding?: boolean;\n brandingText?: string;\n brandingUrl?: string;\n submitText?: string;\n isLoading?: boolean;\n hideRequiredAsterisk?: boolean;\n formName?: string;\n showFormName?: boolean;\n secondaryButton?: SecondaryButton;\n buttonAlign?: string;\n buttonClassName?: string;\n formNameFontSize?: number;\n formNameFontWeight?: 'normal' | 'medium' | 'semibold' | 'bold';\n } = {}\n): HTMLFormElement {\n const form = document.createElement('form');\n form.className = 'forms-expert';\n \n // Hide required asterisks via CSS if configured\n if (options.hideRequiredAsterisk) {\n const style = document.createElement('style');\n style.textContent = '.forms-expert .forms-expert-required { display: none; }';\n form.appendChild(style);\n }\n\n // Form name\n if (options.showFormName !== false && options.formName) {\n const title = document.createElement('h1');\n title.className = 'forms-expert-title';\n title.textContent = options.formName;\n title.style.fontSize = options.formNameFontSize != null ? `${options.formNameFontSize}px` : '1.5rem';\n const weightMap: Record<string, string> = { normal: '400', medium: '500', semibold: '600', bold: '700' };\n title.style.fontWeight = weightMap[options.formNameFontWeight || 'bold'] || '700';\n title.style.marginBottom = '0.5rem';\n form.appendChild(title);\n }\n \n // Render fields with row grouping\n const styling = schema.styling;\n const fields = schema.fields;\n let i = 0;\n while (i < fields.length) {\n const field = fields[i];\n if (field.row != null) {\n const rowFields: FormField[] = [field];\n let j = i + 1;\n while (j < fields.length && fields[j].row === field.row) {\n rowFields.push(fields[j]);\n j++;\n }\n if (rowFields.length > 1) {\n const rowDiv = document.createElement('div');\n rowDiv.style.display = 'flex';\n rowDiv.style.gap = '0.75rem';\n rowDiv.style.flexWrap = 'wrap';\n rowFields.forEach((f) => {\n const wrapper = document.createElement('div');\n const wp = getWidthPercent(f.width);\n if (wp) {\n wrapper.style.flex = `0 0 calc(${wp} - 0.75rem)`;\n } else {\n wrapper.style.flex = '1 1 0';\n }\n wrapper.style.minWidth = '180px';\n const fieldEl = renderField(f, values[f.name], errors[f.name], styling);\n wrapper.appendChild(fieldEl);\n rowDiv.appendChild(wrapper);\n });\n form.appendChild(rowDiv);\n } else {\n const fieldEl = renderField(field, values[field.name], errors[field.name], styling);\n form.appendChild(fieldEl);\n }\n i = j;\n } else {\n const fieldEl = renderField(field, values[field.name], errors[field.name], styling);\n form.appendChild(fieldEl);\n i++;\n }\n }\n \n // Honeypot\n if (options.honeypot) {\n const honeypot = document.createElement('input');\n honeypot.type = 'text';\n honeypot.name = '_hp';\n honeypot.className = 'forms-expert-honeypot';\n honeypot.tabIndex = -1;\n honeypot.autocomplete = 'off';\n form.appendChild(honeypot);\n }\n \n // Hidden page URL\n const pageUrl = document.createElement('input');\n pageUrl.type = 'hidden';\n pageUrl.name = 'pageUrl';\n pageUrl.value = typeof window !== 'undefined' ? window.location.href : '';\n form.appendChild(pageUrl);\n \n // Button wrapper\n const btnWrapper = document.createElement('div');\n btnWrapper.className = 'forms-expert-button-wrapper';\n\n // Submit button\n const button = document.createElement('button');\n button.type = 'submit';\n button.className = addCustomClass('forms-expert-button', options.buttonClassName);\n button.disabled = options.isLoading || false;\n \n if (options.isLoading) {\n button.innerHTML = `\n <span class=\"forms-expert-button-loading\">\n <span class=\"forms-expert-spinner\"></span>\n Submitting...\n </span>\n `;\n } else {\n const btnIcon = styling?.buttonIcon;\n const btnIconPos = styling?.buttonIconPosition || 'left';\n if (btnIcon) {\n button.style.display = 'inline-flex';\n button.style.alignItems = 'center';\n button.style.gap = '0.5rem';\n const iconSpan = document.createElement('span');\n iconSpan.style.display = 'inline-flex';\n iconSpan.style.flexShrink = '0';\n iconSpan.innerHTML = btnIcon;\n const textSpan = document.createElement('span');\n textSpan.textContent = options.submitText || 'Submit';\n if (btnIconPos === 'right') {\n button.appendChild(textSpan);\n button.appendChild(iconSpan);\n } else {\n button.appendChild(iconSpan);\n button.appendChild(textSpan);\n }\n } else {\n button.textContent = options.submitText || 'Submit';\n }\n }\n\n // Secondary button helper\n const sec = options.secondaryButton;\n const createSecondaryLink = (): HTMLAnchorElement | null => {\n if (!sec?.enabled) return null;\n const a = document.createElement('a');\n a.className = 'forms-expert-secondary-btn';\n a.href = sec.href || '#';\n a.style.display = 'inline-flex';\n a.style.alignItems = 'center';\n a.style.gap = '0.5rem';\n if (sec.icon) {\n const iconSpan = document.createElement('span');\n iconSpan.style.display = 'inline-flex';\n iconSpan.style.flexShrink = '0';\n iconSpan.innerHTML = sec.icon;\n const textSpan = document.createElement('span');\n textSpan.textContent = sec.text || 'Learn More';\n if (sec.iconPosition === 'right') {\n a.appendChild(textSpan);\n a.appendChild(iconSpan);\n } else {\n a.appendChild(iconSpan);\n a.appendChild(textSpan);\n }\n } else {\n a.textContent = sec.text || 'Learn More';\n }\n if (sec.openInNewTab) { a.target = '_blank'; a.rel = 'noopener noreferrer'; }\n const btnColor = styling?.primaryColor || '#3b82f6';\n const secColor = sec.color || btnColor;\n if (sec.style === 'filled') {\n a.style.background = secColor;\n a.style.color = sec.textColor || '#ffffff';\n a.style.border = 'none';\n } else if (sec.style === 'outlined') {\n a.style.background = 'transparent';\n a.style.color = sec.textColor || secColor;\n a.style.border = `2px solid ${secColor}`;\n } else if (sec.style === 'link') {\n a.style.background = 'transparent';\n a.style.color = sec.textColor || secColor;\n a.style.border = 'none';\n a.style.textDecoration = 'underline';\n } else {\n a.style.background = 'transparent';\n a.style.color = sec.textColor || secColor;\n a.style.border = 'none';\n }\n if (sec.marginTop != null) a.style.marginTop = `${sec.marginTop}px`;\n if (sec.marginBottom != null) a.style.marginBottom = `${sec.marginBottom}px`;\n if (sec.fontSize != null) a.style.fontSize = `${sec.fontSize}px`;\n return a;\n };\n\n // Inline secondary button (left)\n if (sec?.enabled && sec.position === 'left') {\n const link = createSecondaryLink();\n if (link) btnWrapper.appendChild(link);\n }\n\n btnWrapper.appendChild(button);\n\n // Inline secondary button (right or default)\n if (sec?.enabled && sec.position !== 'left' && sec.position !== 'below') {\n const link = createSecondaryLink();\n if (link) {\n link.style.marginLeft = 'auto';\n btnWrapper.appendChild(link);\n }\n }\n\n form.appendChild(btnWrapper);\n\n // Secondary button (below)\n if (sec?.enabled && sec.position === 'below') {\n const belowDiv = document.createElement('div');\n belowDiv.className = 'forms-expert-secondary-below';\n const secAlign = sec.align || options.buttonAlign || 'left';\n belowDiv.style.justifyContent = secAlign === 'center' ? 'center' : secAlign === 'right' ? 'flex-end' : 'flex-start';\n if (sec.marginTop != null) belowDiv.style.marginTop = `${sec.marginTop}px`;\n if (sec.marginBottom != null) belowDiv.style.marginBottom = `${sec.marginBottom}px`;\n const link = createSecondaryLink();\n if (link) {\n link.style.marginTop = '0';\n link.style.marginBottom = '0';\n belowDiv.appendChild(link);\n }\n form.appendChild(belowDiv);\n }\n \n // Branding\n if (options.showBranding !== false) {\n const brandingText = options.brandingText || 'Powered by Forms Expert';\n const brandingUrl = options.brandingUrl || 'https://mira.io';\n const branding = document.createElement('div');\n branding.className = 'forms-expert-branding';\n branding.innerHTML = `<a href=\"${brandingUrl}\" target=\"_blank\" rel=\"noopener\">${brandingText}</a>`;\n form.appendChild(branding);\n }\n \n return form;\n}\n\n/**\n * Render success message\n */\nexport function renderSuccess(message: string): HTMLElement {\n const container = document.createElement('div');\n container.className = 'forms-expert-success';\n \n container.innerHTML = `\n <svg class=\"forms-expert-success-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M5 13l4 4L19 7\"></path>\n </svg>\n <div class=\"forms-expert-success-message\">${escapeHtml(message)}</div>\n `;\n \n return container;\n}\n\n/**\n * Convert validation errors array to record\n */\nexport function errorsToRecord(errors: ValidationError[]): Record<string, string> {\n return errors.reduce(\n (acc, err) => ({ ...acc, [err.field]: err.message }),\n {}\n );\n}\n","/**\n * Form field types\n */\nexport type BasicFieldType =\n | 'text' | 'email' | 'number' | 'textarea' | 'select'\n | 'checkbox' | 'file' | 'date' | 'hidden';\n\nexport type InteractiveFieldType =\n | 'radio' | 'multiselect' | 'rating' | 'scale' | 'toggle'\n | 'ranking' | 'imageChoice' | 'phone' | 'url' | 'password'\n | 'richText' | 'slider' | 'currency' | 'time' | 'datetime'\n | 'dateRange' | 'address' | 'name' | 'dropdown' | 'colorPicker'\n | 'location' | 'opinionScale' | 'consent';\n\nexport type LayoutFieldType = 'heading' | 'divider' | 'paragraph';\n\nexport type FormFieldType = BasicFieldType | InteractiveFieldType | LayoutFieldType;\n\nexport interface FormFieldOption {\n label: string;\n value: string;\n imageUrl?: string;\n}\n\n/**\n * Form field definition\n */\nexport interface FormField {\n name: string;\n type: FormFieldType;\n label?: string;\n placeholder?: string;\n required?: boolean;\n options?: string[] | FormFieldOption[];\n defaultValue?: unknown;\n maxFileSize?: number;\n allowedMimeTypes?: string[];\n multiple?: boolean;\n min?: number;\n max?: number;\n step?: number;\n ratingMax?: number;\n lowLabel?: string;\n highLabel?: string;\n defaultCountryCode?: string;\n currencyCode?: string;\n currencySymbol?: string;\n addressFields?: ('street' | 'street2' | 'city' | 'state' | 'zip' | 'country')[];\n nameFields?: ('prefix' | 'first' | 'middle' | 'last' | 'suffix')[];\n content?: string;\n paragraphFontSize?: number;\n consentText?: string;\n consentUrl?: string;\n consentFontSize?: number;\n maxLength?: number;\n stepId?: string;\n visibleWhen?: {\n field: string;\n operator: 'eq' | 'neq' | 'contains' | 'gt' | 'lt';\n value: unknown;\n };\n\n // Row layout\n row?: number;\n width?: '1/4' | '1/3' | '1/2' | '2/3' | '3/4' | 'full';\n}\n\n/**\n * Secondary button configuration\n */\nexport interface SecondaryButton {\n enabled: boolean;\n text: string;\n href: string;\n openInNewTab?: boolean;\n position?: 'left' | 'right' | 'below';\n align?: 'left' | 'center' | 'right';\n marginTop?: number;\n marginBottom?: number;\n style?: 'filled' | 'outlined' | 'minimal' | 'link';\n color?: string;\n textColor?: string;\n fontSize?: number;\n icon?: string;\n iconPosition?: 'left' | 'right';\n}\n\n/**\n * Form styling configuration\n */\nexport interface FormStyling {\n theme: 'light' | 'dark' | 'system' | 'custom';\n primaryColor: string;\n backgroundColor: string;\n textColor: string;\n errorColor?: string;\n successColor?: string;\n borderRadius: 'none' | 'sm' | 'md' | 'lg';\n fontSize: 'sm' | 'md' | 'lg' | 'small' | 'medium' | 'large';\n buttonStyle: 'filled' | 'outline' | 'outlined' | 'minimal';\n labelPosition: 'top' | 'left' | 'floating';\n labelClassName?: string;\n fieldClassName?: string;\n buttonClassName?: string;\n customCss?: string;\n // Extended styling (matching hosted form builder)\n fontFamily?: string;\n formWidth?: 'narrow' | 'medium' | 'wide' | 'full';\n fieldLayout?: 'stacked' | 'inline';\n fieldBorderStyle?: 'full' | 'bottom';\n fieldBorderColor?: string;\n fieldBorderRadius?: 'none' | 'small' | 'medium' | 'large' | 'full';\n fieldPaddingX?: number;\n fieldPaddingY?: number;\n separatorColor?: string;\n buttonColor?: string;\n buttonText?: string;\n buttonRadius?: 'none' | 'small' | 'medium' | 'large' | 'full';\n buttonAlign?: 'left' | 'center' | 'right';\n buttonSize?: 'small' | 'medium' | 'large';\n buttonPaddingX?: number;\n buttonPaddingY?: number;\n buttonGradient?: string;\n buttonFullWidth?: boolean;\n buttonFontSize?: number;\n buttonIcon?: string;\n buttonIconPosition?: 'left' | 'right';\n fieldSpacing?: 'compact' | 'normal' | 'relaxed' | 'spacious';\n formPadding?: 'none' | 'compact' | 'normal' | 'relaxed' | 'spacious';\n labelSpacing?: 'compact' | 'normal' | 'relaxed';\n placeholderFontSize?: 'small' | 'medium' | 'large';\n headingSize?: 'small' | 'medium' | 'large' | 'extra-large';\n paragraphSize?: 'small' | 'medium' | 'large';\n formNameFontSize?: number;\n formNameFontWeight?: 'normal' | 'medium' | 'semibold' | 'bold';\n hideRequiredAsterisk?: boolean;\n logoUrl?: string;\n logoPosition?: 'top-left' | 'top-center' | 'top-right';\n coverImageUrl?: string;\n backgroundImageUrl?: string;\n backgroundOverlay?: number;\n transparentBackground?: boolean;\n secondaryButton?: SecondaryButton;\n // Input styling\n inputBackgroundColor?: string;\n placeholderColor?: string;\n}\n\n/**\n * Form schema\n */\nexport interface FormSchema {\n fields: FormField[];\n styling?: FormStyling;\n}\n\n/**\n * Form captcha settings\n */\nexport interface CaptchaSettings {\n enabled: boolean;\n provider?: 'turnstile' | 'recaptcha' | 'hcaptcha';\n siteKey?: string;\n}\n\n/**\n * Form branding configuration\n */\nexport interface FormBranding {\n enabled: boolean;\n text?: string;\n url?: string;\n}\n\n/**\n * Form status response from API\n */\nexport interface FormStatusResponse {\n active: boolean;\n formId?: string;\n name?: string;\n description?: string | null;\n mode?: 'free' | 'schema';\n type?: 'hosted' | 'embed' | 'both';\n layout?: 'single' | 'multi-step';\n schema?: FormSchema;\n steps?: Array<{ title: string; description?: string; fields: string[] }>;\n /** Top-level styling (full hosted styling config) */\n styling?: FormStyling;\n embedConfig?: {\n width?: string;\n height?: string;\n maxHeight?: string;\n minHeight?: string;\n autoResize?: boolean;\n transparentBackground?: boolean;\n [key: string]: unknown;\n };\n error?: string;\n /** Captcha settings (top-level) */\n captcha?: CaptchaSettings;\n settings?: {\n /** @deprecated Use top-level captcha instead */\n captcha?: CaptchaSettings;\n honeypot: boolean;\n allowAttachments: boolean;\n maxAttachments?: number;\n maxAttachmentSize?: number;\n successMessage?: string;\n redirectUrl?: string;\n showFormName?: boolean;\n };\n /** Access control configuration */\n accessControl?: {\n mode: string;\n passwordProtected: boolean;\n };\n /** Branding configuration */\n branding?: FormBranding;\n /** Hosted config (page settings, success page, etc.) */\n hostedConfig?: {\n pageTitle?: string;\n successMessage?: string;\n successPageType?: 'message' | 'redirect' | 'custom';\n redirectUrl?: string;\n customSuccessHtml?: string;\n [key: string]: unknown;\n };\n closesAt?: string | null;\n resourceId?: string;\n /** Available published translation language codes */\n availableLanguages?: string[];\n /** Current language applied to this response (null if base language) */\n currentLanguage?: string | null;\n /** Whether to show language switch UI */\n showLanguageSwitch?: boolean;\n}\n\n/**\n * Validation error\n */\nexport interface ValidationError {\n field: string;\n message: string;\n}\n\n/**\n * Validation response from API\n */\nexport interface ValidationResponse {\n valid: boolean;\n errors: ValidationError[];\n}\n\n/**\n * Submission response from API\n */\nexport interface SubmissionResponse {\n success: boolean;\n submissionId: string;\n message: string;\n}\n\n/**\n * Submit options\n */\nexport interface SubmitOptions {\n pageUrl?: string;\n captchaToken?: string;\n /** Callback for upload progress */\n onProgress?: (progress: UploadProgress) => void;\n}\n\n/**\n * Upload progress information\n */\nexport interface UploadProgress {\n loaded: number;\n total: number;\n percentage: number;\n}\n\n/**\n * File validation error\n */\nexport interface FileValidationError {\n field: string;\n file: string;\n error: 'size' | 'type' | 'count';\n message: string;\n}\n\n/**\n * SDK configuration\n */\nexport interface FormsSDKConfig {\n apiKey: string;\n resourceId: string;\n baseUrl?: string;\n}\n\n/**\n * Form handler options\n */\nexport interface FormHandlerOptions {\n /** Track form views for analytics (completion rate) */\n trackViews?: boolean;\n onSubmitStart?: () => void;\n onSubmitSuccess?: (response: SubmissionResponse) => void;\n onSubmitError?: (error: FormsError) => void;\n onValidationError?: (errors: ValidationError[]) => void;\n}\n\n/**\n * Forms SDK error\n */\nexport class FormsError extends Error {\n constructor(\n message: string,\n public code: string,\n public statusCode: number,\n public retryAfter?: number\n ) {\n super(message);\n this.name = 'FormsError';\n }\n}\n\n/**\n * Validation error class\n */\nexport class FormValidationError extends Error {\n constructor(public errors: ValidationError[]) {\n super('Validation failed');\n this.name = 'FormValidationError';\n }\n}\n","import {\n FormsSDKConfig,\n FormStatusResponse,\n ValidationResponse,\n SubmissionResponse,\n SubmitOptions,\n FormsError,\n UploadProgress,\n} from './types';\n\n/**\n * API client for forms backend\n */\nexport class FormsApiClient {\n private baseUrl: string;\n private apiKey: string;\n private resourceId: string;\n\n constructor(config: FormsSDKConfig) {\n this.apiKey = config.apiKey;\n this.resourceId = config.resourceId;\n this.baseUrl = (config.baseUrl || 'https://api.forms.expert/api/v1').replace(/\\/$/, '');\n }\n\n /**\n * Build URL with token query parameter\n */\n private buildUrl(path: string): string {\n const separator = path.includes('?') ? '&' : '?';\n return `${this.baseUrl}${path}${separator}token=${encodeURIComponent(this.apiKey)}`;\n }\n\n /**\n * Make an API request\n */\n private async request<T>(\n method: string,\n path: string,\n body?: object\n ): Promise<T> {\n const url = this.buildUrl(path);\n\n const response = await fetch(url, {\n method,\n headers: {\n 'Content-Type': 'application/json',\n },\n body: body ? JSON.stringify(body) : undefined,\n });\n\n const data = await response.json();\n\n if (!response.ok) {\n throw new FormsError(\n data.message || 'Request failed',\n data.code || 'UNKNOWN_ERROR',\n response.status,\n data.retryAfter\n );\n }\n\n return data;\n }\n\n /**\n * Check if form is active and get configuration\n */\n async isActive(slug: string, lang?: string): Promise<FormStatusResponse> {\n const langParam = lang ? `?lang=${encodeURIComponent(lang)}` : '';\n return this.request('GET', `/f/${this.resourceId}/${slug}/is-active${langParam}`);\n }\n\n /**\n * Validate form data without submitting\n */\n async validate(\n slug: string,\n data: Record<string, unknown>\n ): Promise<ValidationResponse> {\n return this.request('POST', `/f/${this.resourceId}/${slug}/validate`, {\n data,\n });\n }\n\n /**\n * Submit form data (supports files)\n */\n async submit(\n slug: string,\n data: Record<string, unknown>,\n options?: SubmitOptions\n ): Promise<SubmissionResponse> {\n const url = this.buildUrl(`/f/${this.resourceId}/${slug}`);\n \n // Check if data contains files\n const hasFiles = Object.values(data).some(\n (v) => v instanceof File || (v instanceof FileList && v.length > 0)\n );\n\n if (hasFiles || options?.onProgress) {\n // Use FormData and XMLHttpRequest for file uploads with progress\n return this.submitWithFormData(url, data, options);\n }\n\n // Use regular JSON request for non-file submissions\n return this.request('POST', `/f/${this.resourceId}/${slug}`, {\n data,\n pageUrl: options?.pageUrl || (typeof window !== 'undefined' ? window.location.href : undefined),\n captchaToken: options?.captchaToken,\n });\n }\n\n /**\n * Submit with FormData (for file uploads with progress tracking)\n */\n private submitWithFormData(\n url: string,\n data: Record<string, unknown>,\n options?: SubmitOptions\n ): Promise<SubmissionResponse> {\n return new Promise((resolve, reject) => {\n const formData = new FormData();\n\n // Add data fields\n for (const [key, value] of Object.entries(data)) {\n if (value instanceof File) {\n formData.append(key, value);\n } else if (value instanceof FileList) {\n Array.from(value).forEach((file) => formData.append(key, file));\n } else if (value !== undefined && value !== null) {\n formData.append(`data[${key}]`, String(value));\n }\n }\n\n // Add metadata\n const pageUrl = options?.pageUrl || (typeof window !== 'undefined' ? window.location.href : '');\n if (pageUrl) {\n formData.append('pageUrl', pageUrl);\n }\n if (options?.captchaToken) {\n formData.append('captchaToken', options.captchaToken);\n }\n\n const xhr = new XMLHttpRequest();\n\n // Progress tracking\n if (options?.onProgress) {\n xhr.upload.addEventListener('progress', (event) => {\n if (event.lengthComputable) {\n options.onProgress!({\n loaded: event.loaded,\n total: event.total,\n percentage: Math.round((event.loaded / event.total) * 100),\n });\n }\n });\n }\n\n xhr.addEventListener('load', () => {\n try {\n const response = JSON.parse(xhr.responseText);\n if (xhr.status >= 200 && xhr.status < 300) {\n resolve(response);\n } else {\n reject(new FormsError(\n response.message || 'Submission failed',\n response.code || 'UNKNOWN_ERROR',\n xhr.status,\n response.retryAfter\n ));\n }\n } catch {\n reject(new FormsError('Invalid response', 'PARSE_ERROR', xhr.status));\n }\n });\n\n xhr.addEventListener('error', () => {\n reject(new FormsError('Network error', 'NETWORK_ERROR', 0));\n });\n\n xhr.addEventListener('abort', () => {\n reject(new FormsError('Request aborted', 'ABORTED', 0));\n });\n\n xhr.open('POST', url);\n xhr.send(formData);\n });\n }\n\n /**\n * Track a form view (for analytics completion rate)\n */\n async trackView(slug: string): Promise<void> {\n const url = this.buildUrl(`/f/${this.resourceId}/${slug}/view`);\n await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: '{}' }).catch(() => {});\n }\n\n /**\n * Get resource ID\n */\n getResourceId(): string {\n return this.resourceId;\n }\n\n /**\n * Get base URL\n */\n getBaseUrl(): string {\n return this.baseUrl;\n }\n}\n","import { FormsApiClient } from './api-client';\nimport {\n FormsSDKConfig,\n FormStatusResponse,\n ValidationResponse,\n SubmissionResponse,\n SubmitOptions,\n FormHandlerOptions,\n FormsError,\n FormValidationError,\n} from './types';\n\n/**\n * Form handler for a specific form\n */\nexport class FormHandler {\n private apiClient: FormsApiClient;\n private slug: string;\n private config: FormStatusResponse | null = null;\n private options: FormHandlerOptions;\n\n constructor(\n apiClient: FormsApiClient,\n slug: string,\n options: FormHandlerOptions = {}\n ) {\n this.apiClient = apiClient;\n this.slug = slug;\n this.options = options;\n }\n\n /**\n * Initialize form handler and fetch configuration\n */\n async initialize(lang?: string): Promise<FormStatusResponse> {\n this.config = await this.apiClient.isActive(this.slug, lang);\n if (this.options.trackViews) {\n this.apiClient.trackView(this.slug);\n }\n return this.config;\n }\n\n /**\n * Get cached form configuration\n */\n getConfig(): FormStatusResponse | null {\n return this.config;\n }\n\n /**\n * Check if form is active\n */\n isActive(): boolean {\n return this.config?.active ?? false;\n }\n\n /**\n * Check if captcha is required\n */\n requiresCaptcha(): boolean {\n return this.config?.settings?.captcha?.enabled ?? false;\n }\n\n /**\n * Get captcha provider\n */\n getCaptchaProvider(): 'turnstile' | 'recaptcha' | 'hcaptcha' | undefined {\n return this.config?.settings?.captcha?.provider;\n }\n\n /**\n * Get form schema\n */\n getSchema() {\n return this.config?.schema;\n }\n\n /**\n * Validate form data\n */\n async validate(data: Record<string, unknown>): Promise<ValidationResponse> {\n return this.apiClient.validate(this.slug, data);\n }\n\n /**\n * Submit form data\n */\n async submit(\n data: Record<string, unknown>,\n options?: SubmitOptions\n ): Promise<SubmissionResponse> {\n this.options.onSubmitStart?.();\n\n try {\n // Validate first if in schema mode\n if (this.config?.mode === 'schema') {\n const validation = await this.validate(data);\n if (!validation.valid) {\n this.options.onValidationError?.(validation.errors);\n throw new FormValidationError(validation.errors);\n }\n }\n\n const response = await this.apiClient.submit(this.slug, data, options);\n this.options.onSubmitSuccess?.(response);\n return response;\n } catch (error) {\n if (error instanceof FormsError) {\n this.options.onSubmitError?.(error);\n }\n throw error;\n }\n }\n\n /**\n * Get success message from config\n */\n getSuccessMessage(): string {\n return this.config?.settings?.successMessage || 'Form submitted successfully!';\n }\n\n /**\n * Get redirect URL from config\n */\n getRedirectUrl(): string | undefined {\n return this.config?.settings?.redirectUrl;\n }\n}\n\n/**\n * Main Forms SDK class\n */\nexport class FormsSDK {\n private apiClient: FormsApiClient;\n\n constructor(config: FormsSDKConfig) {\n this.apiClient = new FormsApiClient(config);\n }\n\n /**\n * Check if form is active and get configuration\n */\n async isActive(slug: string, lang?: string): Promise<FormStatusResponse> {\n return this.apiClient.isActive(slug, lang);\n }\n\n /**\n * Validate form data without submitting\n */\n async validate(\n slug: string,\n data: Record<string, unknown>\n ): Promise<ValidationResponse> {\n return this.apiClient.validate(slug, data);\n }\n\n /**\n * Submit form data\n */\n async submit(\n slug: string,\n data: Record<string, unknown>,\n options?: SubmitOptions\n ): Promise<SubmissionResponse> {\n return this.apiClient.submit(slug, data, options);\n }\n\n /**\n * Create a form handler for a specific form\n */\n form(slug: string, options?: FormHandlerOptions): FormHandler {\n return new FormHandler(this.apiClient, slug, options);\n }\n\n /**\n * Track a form view (for analytics completion rate)\n */\n async trackView(slug: string): Promise<void> {\n return this.apiClient.trackView(slug);\n }\n\n /**\n * Submit with retry logic for rate limits\n */\n async submitWithRetry(\n slug: string,\n data: Record<string, unknown>,\n options?: SubmitOptions & { maxRetries?: number }\n ): Promise<SubmissionResponse> {\n const maxRetries = options?.maxRetries ?? 3;\n let lastError: Error | null = null;\n\n for (let attempt = 0; attempt < maxRetries; attempt++) {\n try {\n return await this.submit(slug, data, options);\n } catch (error) {\n lastError = error as Error;\n\n if (error instanceof FormsError) {\n // Don't retry validation or auth errors\n if (\n [\n 'VALIDATION_ERROR',\n 'CAPTCHA_REQUIRED',\n 'ORIGIN_NOT_ALLOWED',\n ].includes(error.code)\n ) {\n throw error;\n }\n\n // Retry rate limits with backoff\n if (error.code.includes('RATE_LIMIT')) {\n const retryAfter = error.retryAfter || Math.pow(2, attempt) * 1000;\n await new Promise((resolve) => setTimeout(resolve, retryAfter));\n continue;\n }\n }\n\n // Exponential backoff for network errors\n await new Promise((resolve) =>\n setTimeout(resolve, Math.pow(2, attempt) * 1000)\n );\n }\n }\n\n throw lastError!;\n }\n}\n","import {\n FormsSDK,\n FormsSDKConfig,\n FormStatusResponse,\n FormStyling,\n SubmissionResponse,\n ValidationError,\n FormValidationError,\n FormsError,\n} from '../core';\nimport { generateFormStyles } from './styles';\nimport { renderForm, renderSuccess, errorsToRecord } from './renderer';\n\nexport interface FormWidgetOptions {\n /** Target element or selector */\n target: string | HTMLElement;\n /** Form slug */\n slug: string;\n /** Track form views for analytics (completion rate). Default: false */\n trackViews?: boolean;\n /** Custom submit button text */\n submitText?: string;\n /** Success callback */\n onSuccess?: (response: SubmissionResponse) => void;\n /** Error callback */\n onError?: (error: Error) => void;\n /** Validation error callback */\n onValidationError?: (errors: ValidationError[]) => void;\n /** Reset form after submission */\n resetOnSuccess?: boolean;\n /** Redirect after success (overrides form config) */\n redirectUrl?: string;\n /** Language code to pass to backend */\n lang?: string;\n}\n\n/**\n * Form widget for embedding forms\n */\nexport class FormWidget {\n private sdk: FormsSDK;\n private container: HTMLElement;\n private config: FormStatusResponse | null = null;\n private values: Record<string, unknown> = {};\n private errors: Record<string, string> = {};\n private isLoading = false;\n private isSubmitted = false;\n private options: FormWidgetOptions;\n private styleEl: HTMLStyleElement | null = null;\n\n constructor(sdkConfig: FormsSDKConfig, options: FormWidgetOptions) {\n this.sdk = new FormsSDK(sdkConfig);\n this.options = options;\n\n // Get container element\n const target = options.target;\n if (typeof target === 'string') {\n const el = document.querySelector(target);\n if (!el) throw new Error(`Element not found: ${target}`);\n this.container = el as HTMLElement;\n } else {\n this.container = target;\n }\n }\n\n /**\n * Initialize and render the form\n */\n async init(): Promise<void> {\n try {\n this.renderLoading();\n this.config = await this.sdk.isActive(this.options.slug, this.options.lang);\n\n if (!this.config.active) {\n this.renderError('This form is not available');\n return;\n }\n\n if (this.options.trackViews) {\n this.sdk.trackView(this.options.slug);\n }\n\n this.injectStyles();\n this.render();\n } catch (error) {\n this.renderError('Failed to load form');\n this.options.onError?.(error as Error);\n }\n }\n\n /**\n * Inject CSS styles\n */\n private injectStyles(): void {\n if (this.styleEl) return;\n\n this.styleEl = document.createElement('style');\n this.styleEl.id = `forms-expert-styles-${this.options.slug}`;\n const mergedStyling = { ...this.config?.schema?.styling, ...this.config?.styling } as FormStyling | undefined;\n this.styleEl.textContent = generateFormStyles(mergedStyling);\n document.head.appendChild(this.styleEl);\n\n // Load Google Font if needed\n this.injectGoogleFont(mergedStyling?.fontFamily);\n }\n\n /**\n * Inject Google Font stylesheet if needed\n */\n private injectGoogleFont(fontFamily?: string): void {\n if (!fontFamily) return;\n \n const googleFonts = ['Inter', 'Roboto', 'Open Sans', 'Lato', 'Poppins', 'Montserrat', 'Nunito', 'Source Sans Pro', 'Raleway', 'Ubuntu', 'Playfair Display', 'Merriweather'];\n const fontToLoad = fontFamily.split(',')[0]?.trim();\n \n if (!fontToLoad || !googleFonts.includes(fontToLoad)) return;\n \n const linkId = `forms-expert-font-${this.options.slug}`;\n if (document.getElementById(linkId)) return;\n \n const link = document.createElement('link');\n link.id = linkId;\n link.rel = 'stylesheet';\n link.href = `https://fonts.googleapis.com/css2?family=${fontToLoad.replace(/ /g, '+')}:wght@400;500;600;700&display=swap`;\n document.head.appendChild(link);\n }\n\n /**\n * Render the form\n */\n private render(): void {\n if (!this.config?.schema) return;\n\n if (this.isSubmitted) {\n this.container.innerHTML = '';\n const successMessage =\n this.config.settings?.successMessage || 'Form submitted successfully!';\n this.container.appendChild(renderSuccess(successMessage));\n return;\n }\n\n const mergedStyling = { ...this.config.schema.styling, ...this.config.styling } as FormStyling;\n const schemaWithStyling = { ...this.config.schema, styling: mergedStyling };\n\n const form = renderForm(schemaWithStyling, this.values, this.errors, {\n honeypot: this.config.settings?.honeypot,\n showBranding: this.config.branding?.enabled !== false,\n brandingText: this.config.branding?.text,\n brandingUrl: this.config.branding?.url,\n submitText: mergedStyling.buttonText || this.options.submitText,\n isLoading: this.isLoading,\n hideRequiredAsterisk: mergedStyling.hideRequiredAsterisk,\n formName: this.config.hostedConfig?.pageTitle as string || this.config.name,\n showFormName: this.config.settings?.showFormName as boolean | undefined,\n secondaryButton: mergedStyling.secondaryButton,\n buttonAlign: mergedStyling.buttonAlign,\n buttonClassName: mergedStyling.buttonClassName,\n formNameFontSize: mergedStyling.formNameFontSize,\n formNameFontWeight: mergedStyling.formNameFontWeight,\n });\n\n // Handle input changes\n form.addEventListener('input', (e) => {\n const target = e.target as HTMLInputElement;\n if (target.name && target.name !== '_hp' && target.name !== 'pageUrl') {\n if (target.type === 'checkbox') {\n this.values[target.name] = target.checked;\n } else if (target.type === 'file') {\n // Store FileList for multiple files, single File for single uploads\n this.values[target.name] = target.multiple ? target.files : target.files?.[0];\n } else {\n this.values[target.name] = target.value;\n }\n // Clear error on change\n if (this.errors[target.name]) {\n delete this.errors[target.name];\n this.render();\n }\n }\n });\n\n // Handle submit\n form.addEventListener('submit', (e) => {\n e.preventDefault();\n this.handleSubmit();\n });\n\n this.container.innerHTML = '';\n this.container.appendChild(form);\n }\n\n /**\n * Handle form submission\n */\n private async handleSubmit(): Promise<void> {\n if (this.isLoading || !this.config) return;\n\n this.isLoading = true;\n this.errors = {};\n this.render();\n\n try {\n const response = await this.sdk.submit(this.options.slug, this.values);\n\n this.isLoading = false;\n this.isSubmitted = true;\n this.render();\n\n this.options.onSuccess?.(response);\n\n // Handle redirect\n const redirectUrl =\n this.options.redirectUrl || this.config.settings?.redirectUrl;\n if (redirectUrl) {\n setTimeout(() => {\n window.location.href = redirectUrl;\n }, 1500);\n }\n\n // Reset form after delay if configured\n if (this.options.resetOnSuccess) {\n setTimeout(() => {\n this.reset();\n }, 3000);\n }\n } catch (error) {\n this.isLoading = false;\n\n if (error instanceof FormValidationError) {\n this.errors = errorsToRecord(error.errors);\n this.options.onValidationError?.(error.errors);\n } else {\n this.options.onError?.(error as Error);\n }\n\n this.render();\n }\n }\n\n /**\n * Reset form to initial state\n */\n reset(): void {\n this.values = {};\n this.errors = {};\n this.isLoading = false;\n this.isSubmitted = false;\n this.render();\n }\n\n /**\n * Render loading spinner\n */\n private renderLoading(): void {\n this.container.innerHTML = `\n <div class=\"forms-expert\" style=\"display: flex; align-items: center; justify-content: center; padding: 2rem;\">\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" style=\"animation: fe-spin 1s linear infinite; color: #9ca3af;\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"3\" fill=\"none\" stroke-dasharray=\"31.4 31.4\" stroke-linecap=\"round\"/>\n </svg>\n </div>\n <style>@keyframes fe-spin { to { transform: rotate(360deg); } }</style>\n `;\n }\n\n /**\n * Render error message\n */\n private renderError(message: string): void {\n this.container.innerHTML = `\n <div class=\"forms-expert\" style=\"text-align: center; padding: 2rem; color: #ef4444;\">\n <p>${message}</p>\n </div>\n `;\n }\n\n /**\n * Destroy widget\n */\n destroy(): void {\n this.container.innerHTML = '';\n this.styleEl?.remove();\n this.styleEl = null;\n }\n}\n\n/**\n * Auto-initialize forms on page load\n */\nexport function autoInit(): void {\n const forms = document.querySelectorAll('[data-forms-expert]');\n\n forms.forEach((el) => {\n const apiKey = el.getAttribute('data-api-key');\n const resourceId = el.getAttribute('data-resource-id');\n const slug = el.getAttribute('data-forms-expert');\n const baseUrl = el.getAttribute('data-base-url') || undefined;\n\n if (!apiKey || !resourceId || !slug) {\n console.error('Forms Expert: Missing required attributes', {\n apiKey: !!apiKey,\n resourceId: !!resourceId,\n slug: !!slug,\n });\n return;\n }\n\n const widget = new FormWidget(\n { apiKey, resourceId, baseUrl },\n {\n target: el as HTMLElement,\n slug,\n trackViews: el.getAttribute('data-track-views') === 'true',\n submitText: el.getAttribute('data-submit-text') || undefined,\n resetOnSuccess: el.getAttribute('data-reset') === 'true',\n lang: el.getAttribute('data-lang') || undefined,\n }\n );\n\n widget.init();\n });\n}\n\n// Auto-init on DOMContentLoaded\nif (typeof window !== 'undefined') {\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', autoInit);\n } else {\n autoInit();\n }\n}\n"],"mappings":"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","names":["defaultStyling","getBorderRadius","radius","getFieldBorderRadius","getButtonRadius","getFontSize","size","getPlaceholderFontSize","getFieldSpacing","spacing","getFormPadding","padding","getLabelSpacing","getFormWidth","width","getButtonAlign","align","generateFormStyles","styling","s","fieldRadius","btnRadius","fontSize","phFontSize","fieldSpacing","formPadding","labelSpacing","formWidth","btnBgColor","btnTextColor","borderColor","separatorColor","fontFamily","btnAlign","btnSize","btnPx","btnPy","btnFs","btnBg","escapeHtml","text","div","getHeadingSizePx","size","getParagraphSizePx","addCustomClass","baseClass","customClass","normalizeOpts","options","o","getWidthPercent","width","renderField","field","value","error","styling","group","h","p","hr","pFontSize","div","input","wrapper","label","text","escapeHtml","link","errorEl","selectWrapper","selectBtn","opts","selectedOpt","labelSpan","arrow","dropdown","opt","item","e","hiddenInput","el","radioGroup","radioWrapper","radioInput","checkGroup","selected","checkWrapper","checkInput","ratingContainer","max","current","star","scaleContainer","min","i","btn","labels","borderColor","mutedColor","primaryColor","dropzone","fileInput","icon","types","sizeInfo","s","rangeContainer","range","startInput","endInput","addrContainer","addrFields","addr","af","inp","nameContainer","nameFields","nameVal","nf","imgContainer","card","img","lbl","rankContainer","row","locContainer","loc","addrInput","coordRow","latInput","lngInput","renderForm","schema","values","errors","form","style","title","weightMap","fields","rowFields","j","rowDiv","f","wp","fieldEl","honeypot","pageUrl","btnWrapper","button","btnIcon","btnIconPos","iconSpan","textSpan","sec","createSecondaryLink","a","btnColor","secColor","belowDiv","secAlign","brandingText","brandingUrl","branding","renderSuccess","message","container","errorsToRecord","acc","err","FormsError","message","code","statusCode","retryAfter","FormValidationError","errors","FormsApiClient","config","path","separator","method","body","url","response","data","FormsError","slug","lang","langParam","options","v","resolve","reject","formData","key","value","file","pageUrl","xhr","event","FormHandler","apiClient","slug","options","lang","data","validation","FormValidationError","response","error","FormsError","FormsSDK","config","FormsApiClient","maxRetries","lastError","attempt","retryAfter","resolve","FormWidget","sdkConfig","options","FormsSDK","target","el","error","mergedStyling","generateFormStyles","fontFamily","googleFonts","fontToLoad","linkId","link","successMessage","renderSuccess","schemaWithStyling","form","renderForm","e","response","redirectUrl","FormValidationError","errorsToRecord","message","autoInit","apiKey","resourceId","slug","baseUrl"]}
1
+ {"version":3,"sources":["../../vanilla/styles.ts","../../vanilla/renderer.ts","../../core/types.ts","../../core/api-client.ts","../../core/forms-sdk.ts","../../vanilla/widget.ts"],"sourcesContent":["import { FormStyling } from '../core/types';\n\nconst defaultStyling: FormStyling = {\n theme: 'light',\n primaryColor: '#3b82f6',\n backgroundColor: '#ffffff',\n textColor: '#1f2937',\n borderRadius: 'md',\n fontSize: 'md',\n buttonStyle: 'filled',\n labelPosition: 'top',\n};\n\nfunction getBorderRadius(radius: FormStyling['borderRadius']): string {\n switch (radius) {\n case 'none': return '0';\n case 'sm': return '0.125rem';\n case 'md': return '0.375rem';\n case 'lg': return '0.5rem';\n default: return '0.375rem';\n }\n}\n\nfunction getFieldBorderRadius(radius?: FormStyling['fieldBorderRadius']): string {\n switch (radius) {\n case 'none': return '0';\n case 'small': return '0.25rem';\n case 'medium': return '0.375rem';\n case 'large': return '0.75rem';\n case 'full': return '9999px';\n default: return '0.375rem';\n }\n}\n\nfunction getButtonRadius(radius?: FormStyling['buttonRadius']): string {\n switch (radius) {\n case 'none': return '0';\n case 'small': return '4px';\n case 'medium': return '8px';\n case 'large': return '12px';\n case 'full': return '9999px';\n default: return '8px';\n }\n}\n\nfunction getFontSize(size: FormStyling['fontSize']): string {\n switch (size) {\n case 'sm': case 'small': return '0.875rem';\n case 'md': case 'medium': return '1rem';\n case 'lg': case 'large': return '1.125rem';\n default: return '1rem';\n }\n}\n\nfunction getPlaceholderFontSize(size?: FormStyling['placeholderFontSize']): string {\n switch (size) {\n case 'small': return '0.75rem';\n case 'large': return '1rem';\n default: return '0.875rem';\n }\n}\n\nfunction getFieldSpacing(spacing?: FormStyling['fieldSpacing']): string {\n switch (spacing) {\n case 'compact': return '0.5rem';\n case 'relaxed': return '1.5rem';\n case 'spacious': return '2rem';\n default: return '1rem';\n }\n}\n\nfunction getFormPadding(padding?: FormStyling['formPadding']): string {\n switch (padding) {\n case 'none': return '0';\n case 'compact': return '1rem';\n case 'relaxed': return '2.5rem';\n case 'spacious': return '3.5rem';\n default: return '1.5rem';\n }\n}\n\nfunction getLabelSpacing(spacing?: FormStyling['labelSpacing']): string {\n switch (spacing) {\n case 'compact': return '0.125rem';\n case 'relaxed': return '0.75rem';\n default: return '0.25rem';\n }\n}\n\nfunction getFormWidth(width?: FormStyling['formWidth']): string {\n switch (width) {\n case 'narrow': return '28rem';\n case 'wide': return '48rem';\n case 'full': return '100%';\n default: return '36rem';\n }\n}\n\nfunction getButtonAlign(align?: FormStyling['buttonAlign']): string {\n switch (align) {\n case 'left': return 'flex-start';\n case 'right': return 'flex-end';\n default: return 'center';\n }\n}\n\nexport function generateFormStyles(styling: FormStyling = defaultStyling): string {\n const s = { ...defaultStyling, ...styling };\n const radius = getBorderRadius(s.borderRadius);\n const fieldRadius = getFieldBorderRadius(s.fieldBorderRadius);\n const btnRadius = getButtonRadius(s.buttonRadius);\n const fontSize = getFontSize(s.fontSize);\n const phFontSize = getPlaceholderFontSize(s.placeholderFontSize);\n const fieldSpacing = getFieldSpacing(s.fieldSpacing);\n const formPadding = getFormPadding(s.formPadding);\n const labelSpacing = getLabelSpacing(s.labelSpacing);\n const formWidth = getFormWidth(s.formWidth);\n const btnBgColor = s.primaryColor;\n const btnTextColor = s.buttonColor;\n const borderColor = s.fieldBorderColor || (s.theme === 'dark' ? '#4b5563' : '#d1d5db');\n const separatorColor = s.separatorColor || (s.theme === 'dark' ? '#4b5563' : '#d1d5db');\n // Normalize font family - support legacy single values by adding fallbacks\n // For SDK embedded forms, default to 'inherit' so the form uses the website's font\n const fontFamily = s.fontFamily \n ? (s.fontFamily.includes(',') ? s.fontFamily : `${s.fontFamily}, sans-serif`)\n : 'inherit';\n const btnAlign = getButtonAlign(s.buttonAlign);\n\n const btnSizeMap: Record<string, { px: string; py: string; fs: string }> = {\n small: { px: '0.75rem', py: '0.375rem', fs: '0.875rem' },\n medium: { px: '1.25rem', py: '0.625rem', fs: '1rem' },\n large: { px: '1.75rem', py: '0.875rem', fs: '1.125rem' },\n };\n const btnSize = btnSizeMap[s.buttonSize || 'medium'];\n const btnPx = s.buttonPaddingX != null ? `${s.buttonPaddingX}px` : btnSize.px;\n const btnPy = s.buttonPaddingY != null ? `${s.buttonPaddingY}px` : btnSize.py;\n const btnFs = s.buttonFontSize != null ? `${s.buttonFontSize}px` : btnSize.fs;\n const btnBg = s.buttonGradient || (s.buttonStyle === 'filled' ? btnBgColor : 'transparent');\n\n return `\n.forms-expert-wrapper {\n ${s.backgroundImageUrl ? `background-image: url(${s.backgroundImageUrl}); background-size: cover; background-position: center;` : ''}\n ${!s.backgroundImageUrl ? `background-color: ${s.backgroundColor};` : ''}\n position: relative;\n}\n\n.forms-expert-overlay {\n position: absolute;\n inset: 0;\n background-color: rgba(0,0,0,${s.backgroundOverlay || 0});\n pointer-events: none;\n}\n\n.forms-expert {\n font-family: ${fontFamily};\n font-size: ${fontSize};\n color: ${s.textColor};\n background-color: ${s.transparentBackground ? 'transparent' : s.backgroundColor};\n padding: ${formPadding};\n border-radius: ${radius};\n box-sizing: border-box;\n max-width: ${formWidth};\n width: 100%;\n margin: 0 auto;\n position: relative;\n}\n\n.forms-expert * {\n box-sizing: border-box;\n}\n\n.forms-expert-logo {\n display: block;\n max-height: 48px;\n margin-bottom: 1rem;\n}\n.forms-expert-logo-top-left { text-align: left; }\n.forms-expert-logo-top-center { text-align: center; }\n.forms-expert-logo-top-right { text-align: right; }\n.forms-expert-logo img { max-height: 48px; }\n\n.forms-expert-cover {\n width: 100%;\n max-height: 200px;\n object-fit: cover;\n border-radius: ${radius} ${radius} 0 0;\n margin-bottom: 1rem;\n}\n\n.forms-expert-group {\n margin-bottom: ${fieldSpacing};\n ${s.labelPosition === 'left' || s.fieldLayout === 'inline' ? 'display: flex; align-items: flex-start; gap: 1rem;' : ''}\n}\n\n.forms-expert-label {\n display: block;\n font-weight: 500;\n color: ${s.textColor};\n ${s.labelPosition === 'left' || s.fieldLayout === 'inline'\n ? `width: 33%; flex-shrink: 0; padding-top: 0.5rem; margin-bottom: 0;`\n : `margin-bottom: ${labelSpacing};`\n }\n}\n\n.forms-expert-required {\n color: #ef4444;\n margin-left: 0.25rem;\n}\n\n.forms-expert-input-wrapper {\n ${s.labelPosition === 'left' || s.fieldLayout === 'inline' ? 'flex: 1;' : ''}\n}\n\n.forms-expert-input,\n.forms-expert-textarea,\n.forms-expert-select {\n width: 100%;\n padding: ${s.fieldPaddingX != null || s.fieldPaddingY != null ? `${s.fieldPaddingY ?? 8}px ${s.fieldPaddingX ?? 12}px` : '0.5rem 0.75rem'};\n border: ${s.fieldBorderStyle === 'bottom' ? 'none' : `1px solid ${borderColor}`};\n ${s.fieldBorderStyle === 'bottom' ? `border-bottom: 1px solid ${borderColor};` : ''}\n border-radius: ${s.fieldBorderStyle === 'bottom' ? '0' : fieldRadius};\n font-size: ${fontSize};\n font-family: inherit;\n background-color: ${s.inputBackgroundColor || (s.theme === 'dark' ? '#374151' : '#ffffff')};\n color: ${s.textColor};\n transition: border-color 0.15s, box-shadow 0.15s;\n}\n\n.forms-expert-input::placeholder,\n.forms-expert-textarea::placeholder {\n font-size: ${phFontSize};${s.placeholderColor ? `\\n color: ${s.placeholderColor};` : ''}\n}\n\n.forms-expert-input:focus,\n.forms-expert-textarea:focus,\n.forms-expert-select:focus {\n outline: none !important;\n border-color: ${s.primaryColor} !important;\n box-shadow: 0 0 0 2px ${s.primaryColor}33 !important;\n -webkit-appearance: none;\n}\n\n.forms-expert-input.forms-expert-error,\n.forms-expert-textarea.forms-expert-error,\n.forms-expert-select.forms-expert-error {\n border-color: #ef4444;\n}\n\n.forms-expert-select-dropdown {\n position: absolute;\n top: 100%;\n left: 0;\n right: 0;\n z-index: 50;\n margin-top: 4px;\n background-color: ${s.inputBackgroundColor || (s.theme === 'dark' ? '#374151' : '#ffffff')};\n border: 1px solid ${borderColor};\n border-radius: ${fieldRadius};\n box-shadow: 0 4px 12px rgba(0,0,0,0.15);\n max-height: 200px;\n overflow-y: auto;\n}\n\n.forms-expert-select-option {\n padding: ${s.fieldPaddingX != null || s.fieldPaddingY != null ? `${s.fieldPaddingY ?? 8}px ${s.fieldPaddingX ?? 12}px` : '0.5rem 0.75rem'};\n cursor: pointer;\n font-size: ${fontSize};\n transition: background-color 0.1s;\n}\n\n.forms-expert-select-option:hover {\n background-color: ${s.primaryColor}15;\n}\n\n.forms-expert-select-option.active {\n background-color: ${s.primaryColor}20;\n}\n\n.forms-expert-textarea {\n min-height: 100px;\n resize: vertical;\n}\n\n.forms-expert-checkbox-group {\n display: flex;\n align-items: flex-start;\n gap: 0.5rem;\n margin-bottom: ${fieldSpacing};\n}\n\n.forms-expert-checkbox {\n width: 1rem;\n height: 1rem;\n margin-top: 0.125rem;\n flex-shrink: 0;\n accent-color: ${s.primaryColor};\n background-color: transparent;\n cursor: pointer;\n}\n\n.forms-expert-file-wrapper {\n position: relative;\n}\n\n.forms-expert-dropzone {\n position: relative;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 0.5rem;\n border: 2px dashed ${borderColor};\n border-radius: ${fieldRadius};\n padding: 1.5rem;\n cursor: pointer;\n transition: border-color 0.15s, background-color 0.15s;\n}\n\n.forms-expert-dropzone:hover {\n border-color: ${s.primaryColor}80;\n background-color: ${s.theme === 'dark' ? 'rgba(255,255,255,0.05)' : 'rgba(0,0,0,0.02)'};\n}\n\n.forms-expert-file {\n width: 100%;\n padding: 0.5rem 0.75rem;\n border: ${s.fieldBorderStyle === 'bottom' ? 'none' : `1px solid ${borderColor}`};\n ${s.fieldBorderStyle === 'bottom' ? `border-bottom: 1px solid ${borderColor};` : ''}\n border-radius: ${s.fieldBorderStyle === 'bottom' ? '0' : fieldRadius};\n font-size: ${fontSize};\n background-color: ${s.inputBackgroundColor || (s.theme === 'dark' ? '#374151' : '#ffffff')};\n cursor: pointer;\n}\n\n.forms-expert-error-message {\n color: ${s.errorColor || '#ef4444'};\n font-size: 0.875rem;\n margin-top: 0.25rem;\n}\n\n.forms-expert-divider {\n border: none;\n border-top: 1px solid ${separatorColor};\n margin: ${fieldSpacing} 0;\n}\n\n.forms-expert-button-wrapper {\n display: flex;\n justify-content: ${btnAlign};\n margin-top: 1rem;\n gap: 0.5rem;\n flex-wrap: wrap;\n}\n\n.forms-expert-button {\n ${s.buttonFullWidth ? 'width: 100%;' : (s.buttonAlign ? '' : 'width: 100%;')}\n padding: ${btnPy} ${btnPx};\n font-weight: 500;\n font-size: ${btnFs};\n font-family: inherit;\n border-radius: ${btnRadius};\n cursor: pointer;\n transition: opacity 0.2s, transform 0.1s;\n max-width: 100%;\n box-sizing: border-box;\n flex-shrink: 1;\n min-width: 0;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n ${s.buttonStyle === 'filled' \n ? `background: ${btnBg}; color: ${btnTextColor || 'white'}; border: none;`\n : `background: transparent; color: ${btnBgColor}; border: 2px solid ${btnBgColor};`\n }\n}\n\n.forms-expert-button:hover {\n filter: brightness(0.9);\n}\n\n.forms-expert-button:active {\n transform: scale(0.98);\n filter: brightness(0.85);\n}\n\n.forms-expert-button:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n transform: none;\n}\n\n.forms-expert-button-loading {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.5rem;\n}\n\n.forms-expert-spinner {\n width: 1rem;\n height: 1rem;\n border: 2px solid transparent;\n border-top-color: currentColor;\n border-radius: 50%;\n animation: forms-expert-spin 0.6s linear infinite;\n}\n\n@keyframes forms-expert-spin {\n to { transform: rotate(360deg); }\n}\n\n.forms-expert-honeypot {\n position: absolute;\n left: -9999px;\n opacity: 0;\n}\n\n.forms-expert-success {\n text-align: center;\n padding: 2rem;\n color: ${s.textColor};\n}\n\n.forms-expert-success-icon {\n width: 3rem;\n height: 3rem;\n margin: 0 auto 1rem;\n color: ${s.successColor || '#22c55e'};\n}\n\n.forms-expert-success-message {\n font-size: 1.125rem;\n font-weight: 500;\n margin-bottom: 0.5rem;\n}\n\n.forms-expert-branding {\n text-align: center;\n margin-top: 1rem;\n padding-top: 0.75rem;\n border-top: 1px solid ${separatorColor};\n}\n\n.forms-expert-branding a {\n color: ${s.theme === 'dark' ? '#9ca3af' : '#6b7280'};\n text-decoration: none;\n font-size: 0.75rem;\n}\n\n.forms-expert-branding a:hover {\n text-decoration: underline;\n}\n\n.forms-expert-secondary-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n padding: 0.625rem 1.25rem;\n font-weight: 500;\n font-size: ${fontSize};\n font-family: inherit;\n border-radius: ${btnRadius};\n cursor: pointer;\n transition: opacity 0.2s;\n text-decoration: none;\n max-width: 100%;\n box-sizing: border-box;\n flex-shrink: 1;\n min-width: 0;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.forms-expert-secondary-btn:hover { filter: brightness(0.9); }\n.forms-expert-secondary-btn:active { filter: brightness(0.85); }\n\n.forms-expert-secondary-below {\n display: flex;\n margin-top: 0.5rem;\n}\n\n/* Rating stars */\n.forms-expert-rating { display: flex; gap: 0.25rem; }\n.forms-expert-rating-star {\n width: 2rem; height: 2rem; cursor: pointer; border: none;\n background: none; padding: 0; font-size: 1.5rem; color: ${s.theme === 'dark' ? '#4b5563' : '#d1d5db'};\n transition: color 0.15s;\n}\n.forms-expert-rating-star.active { color: #f59e0b; }\n\n/* Scale buttons */\n.forms-expert-scale { display: flex; gap: 0.25rem; flex-wrap: wrap; }\n.forms-expert-scale-labels { display: flex; justify-content: space-between; font-size: 0.75rem; color: ${s.theme === 'dark' ? '#9ca3af' : '#6b7280'}; margin-top: 0.25rem; }\n.forms-expert-scale-btn {\n min-width: 2.25rem; height: 2.25rem; border-radius: ${radius}; cursor: pointer;\n border: 1px solid ${s.theme === 'dark' ? '#4b5563' : '#d1d5db'};\n background: ${s.theme === 'dark' ? '#374151' : '#ffffff'}; color: ${s.textColor};\n font-size: 0.875rem; transition: all 0.15s;\n}\n.forms-expert-scale-btn.active {\n background-color: ${s.primaryColor}; color: white; border-color: ${s.primaryColor};\n}\n\n/* Radio & multiselect groups */\n.forms-expert-radio-group,\n.forms-expert-multiselect-group {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n width: 100%;\n padding: ${s.fieldPaddingX != null || s.fieldPaddingY != null ? `${s.fieldPaddingY ?? 8}px ${s.fieldPaddingX ?? 12}px` : '0.5rem 0.75rem'};\n border: ${s.fieldBorderStyle === 'bottom' ? 'none' : `1px solid ${borderColor}`};\n ${s.fieldBorderStyle === 'bottom' ? `border-bottom: 1px solid ${borderColor};` : ''}\n border-radius: ${s.fieldBorderStyle === 'bottom' ? '0' : fieldRadius};\n background-color: ${s.inputBackgroundColor || (s.theme === 'dark' ? '#374151' : '#ffffff')};\n box-sizing: border-box;\n}\n.forms-expert-radio-item,\n.forms-expert-multiselect-item { display: flex; align-items: center; gap: 0.5rem; cursor: pointer; }\n.forms-expert-radio-item input,\n.forms-expert-multiselect-item input { accent-color: ${s.primaryColor}; }\n\n/* Slider */\n.forms-expert-slider { width: 100%; accent-color: ${s.primaryColor}; }\n.forms-expert-slider-value { text-align: center; font-size: 0.875rem; margin-top: 0.25rem; }\n\n/* Image choice */\n.forms-expert-image-choice { display: flex; flex-wrap: wrap; gap: 0.5rem; }\n.forms-expert-image-choice-item {\n border: 2px solid ${s.theme === 'dark' ? '#4b5563' : '#d1d5db'}; border-radius: ${radius};\n padding: 0.5rem; cursor: pointer; text-align: center; transition: border-color 0.15s;\n}\n.forms-expert-image-choice-item.active { border-color: ${s.primaryColor}; }\n.forms-expert-image-choice-item img { max-width: 80px; max-height: 80px; object-fit: cover; border-radius: ${radius}; }\n\n/* Responsive button scaling */\n@media (max-width: 480px) {\n .forms-expert-button,\n .forms-expert-secondary-btn {\n padding-left: max(0.5rem, min(${btnPx}, 3vw));\n padding-right: max(0.5rem, min(${btnPx}, 3vw));\n font-size: max(0.75rem, min(${btnFs}, 3.5vw));\n }\n}\n\n${s.customCss || ''}\n`.trim();\n}\n","import { FormField, FormSchema, FormStyling, SecondaryButton, ValidationError } from '../core/types';\n\n/**\n * Escape HTML special characters\n */\nfunction escapeHtml(text: string): string {\n const div = document.createElement('div');\n div.textContent = text;\n return div.innerHTML;\n}\n\n/**\n * Layout field types that don't capture data\n */\nconst LAYOUT_TYPES = new Set(['heading', 'divider', 'paragraph']);\n\n/**\n * Heading size map\n */\nfunction getHeadingSizePx(size?: string): string {\n switch (size) {\n case 'small': return '18px';\n case 'large': return '30px';\n case 'extra-large': return '36px';\n default: return '24px';\n }\n}\n\n/**\n * Paragraph size map\n */\nfunction getParagraphSizePx(size?: string): string {\n switch (size) {\n case 'small': return '14px';\n case 'large': return '18px';\n default: return '16px';\n }\n}\n\n/**\n * Helper to add custom class names to elements\n */\nfunction addCustomClass(baseClass: string, customClass?: string): string {\n return customClass ? `${baseClass} ${customClass}` : baseClass;\n}\n\nfunction normalizeOpts(options: unknown[]): { value: string; label: string }[] {\n return options.map((o) => typeof o === 'string' ? { value: o, label: o } : o as { value: string; label: string });\n}\n\nfunction getWidthPercent(width?: string): string | undefined {\n switch (width) {\n case '1/4': return '25%';\n case '1/3': return '33.333%';\n case '1/2': return '50%';\n case '2/3': return '66.666%';\n case '3/4': return '75%';\n case 'full': return '100%';\n default: return undefined;\n }\n}\n\n/**\n * Create a form field element\n */\nexport function renderField(\n field: FormField,\n value: unknown,\n error?: string,\n styling?: Partial<FormStyling>\n): HTMLElement {\n const group = document.createElement('div');\n\n // Layout fields\n if (field.type === 'heading') {\n group.className = 'forms-expert-group';\n const h = document.createElement('h3');\n h.className = 'forms-expert-heading';\n h.style.fontSize = getHeadingSizePx(styling?.headingSize);\n h.textContent = field.label || '';\n group.appendChild(h);\n if (field.content) {\n const p = document.createElement('p');\n p.className = 'forms-expert-heading-subtitle';\n p.textContent = field.content;\n group.appendChild(p);\n }\n return group;\n }\n\n if (field.type === 'divider') {\n const hr = document.createElement('hr');\n hr.className = 'forms-expert-divider';\n return hr;\n }\n\n if (field.type === 'paragraph') {\n group.className = 'forms-expert-group';\n const pFontSize = field.paragraphFontSize\n ? `${field.paragraphFontSize}px`\n : getParagraphSizePx(styling?.paragraphSize);\n if (field.label) {\n const p = document.createElement('p');\n p.className = 'forms-expert-paragraph-label';\n p.style.fontSize = pFontSize;\n p.textContent = field.label;\n group.appendChild(p);\n }\n if (field.content) {\n const div = document.createElement('div');\n div.className = 'forms-expert-paragraph';\n div.style.fontSize = pFontSize;\n div.innerHTML = field.content;\n group.appendChild(div);\n }\n return group;\n }\n\n // Hidden field\n if (field.type === 'hidden') {\n const input = document.createElement('input');\n input.type = 'hidden';\n input.name = field.name;\n input.value = String(field.defaultValue ?? value ?? '');\n group.appendChild(input);\n group.style.display = 'none';\n return group;\n }\n\n // Checkbox / toggle / consent\n if (field.type === 'checkbox' || field.type === 'toggle' || field.type === 'consent') {\n group.className = 'forms-expert-checkbox-group';\n \n const input = document.createElement('input');\n input.type = 'checkbox';\n input.id = `mira-field-${field.name}`;\n input.name = field.name;\n input.className = 'forms-expert-checkbox';\n input.checked = Boolean(value);\n if (field.required) input.required = true;\n \n const wrapper = document.createElement('div');\n\n const label = document.createElement('label');\n label.htmlFor = input.id;\n label.style.cursor = 'pointer';\n if (field.type === 'consent' && field.consentFontSize) {\n label.style.fontSize = `${field.consentFontSize}px`;\n }\n const text = field.type === 'consent' ? (field.consentText || field.label || field.name) : (field.label || field.name);\n label.innerHTML = `${escapeHtml(text)}${field.required ? '<span class=\"forms-expert-required\">*</span>' : ''}`;\n wrapper.appendChild(label);\n\n if (field.type === 'consent' && field.consentUrl) {\n const link = document.createElement('a');\n link.href = field.consentUrl;\n link.target = '_blank';\n link.rel = 'noopener noreferrer';\n link.textContent = 'View policy';\n link.className = 'forms-expert-consent-link';\n wrapper.appendChild(link);\n }\n \n group.appendChild(input);\n group.appendChild(wrapper);\n\n if (error) {\n const errorEl = document.createElement('div');\n errorEl.className = 'forms-expert-error-message';\n errorEl.textContent = error;\n group.appendChild(errorEl);\n }\n return group;\n }\n\n // All other fields\n group.className = 'forms-expert-group';\n \n // Label\n if (field.label) {\n const label = document.createElement('label');\n label.className = `forms-expert-label${styling?.labelClassName ? ' ' + styling.labelClassName : ''}`;\n label.htmlFor = `mira-field-${field.name}`;\n label.innerHTML = `${escapeHtml(field.label)}${field.required ? '<span class=\"forms-expert-required\">*</span>' : ''}`;\n group.appendChild(label);\n }\n \n // Input wrapper\n const wrapper = document.createElement('div');\n wrapper.className = 'forms-expert-input-wrapper';\n \n let input: HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement;\n \n switch (field.type) {\n case 'textarea':\n case 'richText':\n input = document.createElement('textarea');\n input.className = addCustomClass('forms-expert-textarea', styling?.fieldClassName);\n input.value = String(value || '');\n if (field.maxLength) input.maxLength = field.maxLength;\n break;\n \n case 'select':\n case 'dropdown': {\n const selectWrapper = document.createElement('div');\n selectWrapper.style.position = 'relative';\n selectWrapper.style.width = '100%';\n if (styling?.fieldClassName) selectWrapper.className = styling.fieldClassName;\n\n const selectBtn = document.createElement('button');\n selectBtn.type = 'button';\n selectBtn.className = 'forms-expert-select';\n selectBtn.style.display = 'flex';\n selectBtn.style.alignItems = 'center';\n selectBtn.style.justifyContent = 'space-between';\n selectBtn.style.cursor = 'pointer';\n selectBtn.style.textAlign = 'left';\n selectBtn.style.width = '100%';\n\n const opts = normalizeOpts(field.options || []);\n const selectedOpt = opts.find((o) => o.value === String(value || ''));\n\n const labelSpan = document.createElement('span');\n labelSpan.textContent = selectedOpt?.label || field.placeholder || 'Select an option...';\n if (!selectedOpt && styling?.placeholderColor) labelSpan.style.color = styling.placeholderColor;\n selectBtn.appendChild(labelSpan);\n\n const arrow = document.createElement('span');\n arrow.innerHTML = '<svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\"><path d=\"M3 4.5L6 7.5L9 4.5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>';\n arrow.style.flexShrink = '0';\n arrow.style.opacity = '0.5';\n selectBtn.appendChild(arrow);\n\n const dropdown = document.createElement('div');\n dropdown.className = 'forms-expert-select-dropdown';\n dropdown.style.display = 'none';\n\n opts.forEach((opt) => {\n const item = document.createElement('div');\n item.className = 'forms-expert-select-option';\n item.textContent = opt.label;\n if (String(value || '') === opt.value) item.classList.add('active');\n item.addEventListener('mousedown', (e) => {\n e.preventDefault();\n hiddenInput.value = opt.value;\n labelSpan.textContent = opt.label;\n if (styling?.placeholderColor) labelSpan.style.color = '';\n dropdown.querySelectorAll('.forms-expert-select-option').forEach((el) => el.classList.remove('active'));\n item.classList.add('active');\n dropdown.style.display = 'none';\n hiddenInput.dispatchEvent(new Event('input', { bubbles: true }));\n });\n dropdown.appendChild(item);\n });\n\n selectBtn.addEventListener('click', () => {\n dropdown.style.display = dropdown.style.display === 'none' ? 'block' : 'none';\n });\n selectBtn.addEventListener('blur', () => {\n setTimeout(() => { dropdown.style.display = 'none'; }, 150);\n });\n\n const hiddenInput = document.createElement('input');\n hiddenInput.type = 'hidden';\n hiddenInput.name = field.name;\n hiddenInput.value = String(value || '');\n if (field.required) hiddenInput.required = true;\n\n selectWrapper.appendChild(selectBtn);\n selectWrapper.appendChild(dropdown);\n selectWrapper.appendChild(hiddenInput);\n\n wrapper.appendChild(selectWrapper);\n if (error) {\n const errorEl = document.createElement('div');\n errorEl.className = 'forms-expert-error-message';\n errorEl.textContent = error;\n wrapper.appendChild(errorEl);\n }\n group.appendChild(wrapper);\n return group;\n }\n\n case 'radio': {\n // Render as radio group\n const radioGroup = document.createElement('div');\n radioGroup.className = 'forms-expert-radio-group';\n const opts = (field.options || []) as string[];\n opts.forEach((opt) => {\n const radioWrapper = document.createElement('label');\n radioWrapper.className = 'forms-expert-radio-item';\n const radioInput = document.createElement('input');\n radioInput.type = 'radio';\n radioInput.name = field.name;\n radioInput.value = opt;\n radioInput.checked = value === opt;\n radioWrapper.appendChild(radioInput);\n radioWrapper.appendChild(document.createTextNode(` ${opt}`));\n radioGroup.appendChild(radioWrapper);\n });\n wrapper.appendChild(radioGroup);\n if (error) {\n const errorEl = document.createElement('div');\n errorEl.className = 'forms-expert-error-message';\n errorEl.textContent = error;\n wrapper.appendChild(errorEl);\n }\n group.appendChild(wrapper);\n return group;\n }\n\n case 'multiselect': {\n const checkGroup = document.createElement('div');\n checkGroup.className = 'forms-expert-multiselect-group';\n const selected = (value as string[]) || [];\n const opts = (field.options || []) as string[];\n opts.forEach((opt) => {\n const checkWrapper = document.createElement('label');\n checkWrapper.className = 'forms-expert-checkbox-item';\n const checkInput = document.createElement('input');\n checkInput.type = 'checkbox';\n checkInput.name = field.name;\n checkInput.value = opt;\n checkInput.checked = selected.includes(opt);\n checkWrapper.appendChild(checkInput);\n checkWrapper.appendChild(document.createTextNode(` ${opt}`));\n checkGroup.appendChild(checkWrapper);\n });\n wrapper.appendChild(checkGroup);\n if (error) {\n const errorEl = document.createElement('div');\n errorEl.className = 'forms-expert-error-message';\n errorEl.textContent = error;\n wrapper.appendChild(errorEl);\n }\n group.appendChild(wrapper);\n return group;\n }\n\n case 'rating': {\n const ratingContainer = document.createElement('div');\n ratingContainer.className = 'forms-expert-rating';\n const max = field.ratingMax || 5;\n const current = (value as number) || 0;\n for (let i = 1; i <= max; i++) {\n const star = document.createElement('button');\n star.type = 'button';\n star.className = `forms-expert-rating-star ${i <= current ? 'active' : ''}`;\n star.textContent = '★';\n star.dataset.value = String(i);\n ratingContainer.appendChild(star);\n }\n wrapper.appendChild(ratingContainer);\n if (error) {\n const errorEl = document.createElement('div');\n errorEl.className = 'forms-expert-error-message';\n errorEl.textContent = error;\n wrapper.appendChild(errorEl);\n }\n group.appendChild(wrapper);\n return group;\n }\n\n case 'scale':\n case 'opinionScale': {\n const scaleContainer = document.createElement('div');\n scaleContainer.className = 'forms-expert-scale';\n const min = field.min ?? (field.type === 'opinionScale' ? 0 : 1);\n const max = field.max ?? (field.type === 'opinionScale' ? 10 : 5);\n const current = value as number | undefined;\n for (let i = min; i <= max; i++) {\n const btn = document.createElement('button');\n btn.type = 'button';\n btn.className = `forms-expert-scale-btn ${current === i ? 'active' : ''}`;\n btn.textContent = String(i);\n btn.dataset.value = String(i);\n scaleContainer.appendChild(btn);\n }\n wrapper.appendChild(scaleContainer);\n if (field.lowLabel || field.highLabel) {\n const labels = document.createElement('div');\n labels.className = 'forms-expert-scale-labels';\n labels.innerHTML = `<span>${escapeHtml(field.lowLabel || '')}</span><span>${escapeHtml(field.highLabel || '')}</span>`;\n wrapper.appendChild(labels);\n }\n if (error) {\n const errorEl = document.createElement('div');\n errorEl.className = 'forms-expert-error-message';\n errorEl.textContent = error;\n wrapper.appendChild(errorEl);\n }\n group.appendChild(wrapper);\n return group;\n }\n\n case 'slider': {\n input = document.createElement('input');\n input.type = 'range';\n input.className = 'forms-expert-slider';\n input.min = String(field.min ?? 0);\n input.max = String(field.max ?? 100);\n input.step = String(field.step ?? 1);\n input.value = String(value ?? field.min ?? 0);\n break;\n }\n\n case 'file': {\n const borderColor = styling?.theme === 'dark' ? '#4b5563' : '#d1d5db';\n const mutedColor = styling?.theme === 'dark' ? '#9ca3af' : '#6b7280';\n const primaryColor = styling?.primaryColor || '#3b82f6';\n\n const dropzone = document.createElement('label');\n dropzone.htmlFor = `mira-field-${field.name}`;\n dropzone.className = 'forms-expert-dropzone';\n\n const fileInput = document.createElement('input');\n fileInput.id = `mira-field-${field.name}`;\n fileInput.name = field.name;\n fileInput.type = 'file';\n fileInput.style.cssText = 'position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0';\n if (field.allowedMimeTypes?.length) fileInput.accept = field.allowedMimeTypes.join(',');\n if (field.multiple) fileInput.multiple = true;\n dropzone.appendChild(fileInput);\n\n const icon = document.createElement('div');\n icon.innerHTML = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"32\" height=\"32\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"${mutedColor}\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\"/><polyline points=\"17 8 12 3 7 8\"/><line x1=\"12\" x2=\"12\" y1=\"3\" y2=\"15\"/></svg>`;\n dropzone.appendChild(icon);\n\n const text = document.createElement('span');\n text.style.cssText = 'font-size:0.875rem;font-weight:500';\n text.textContent = 'Drag & drop a file here, or click to browse';\n dropzone.appendChild(text);\n\n if (field.allowedMimeTypes?.length) {\n const types = document.createElement('span');\n types.style.cssText = `font-size:0.75rem;color:${mutedColor}`;\n types.textContent = field.allowedMimeTypes.join(', ');\n dropzone.appendChild(types);\n }\n if (field.maxFileSize) {\n const sizeInfo = document.createElement('span');\n sizeInfo.style.cssText = `font-size:0.75rem;color:${mutedColor}`;\n const s = field.maxFileSize;\n sizeInfo.textContent = `Max size: ${s < 1048576 ? `${(s / 1024).toFixed(0)} KB` : `${(s / 1048576).toFixed(0)} MB`}`;\n dropzone.appendChild(sizeInfo);\n }\n\n dropzone.addEventListener('dragover', (e) => { e.preventDefault(); dropzone.style.borderColor = primaryColor; dropzone.style.backgroundColor = styling?.theme === 'dark' ? 'rgba(255,255,255,0.08)' : 'rgba(0,0,0,0.04)'; });\n dropzone.addEventListener('dragleave', () => { dropzone.style.borderColor = borderColor; dropzone.style.backgroundColor = 'transparent'; });\n dropzone.addEventListener('drop', (e) => {\n e.preventDefault();\n dropzone.style.borderColor = borderColor;\n dropzone.style.backgroundColor = 'transparent';\n });\n\n group.appendChild(dropzone);\n if (error) {\n const errorEl = document.createElement('div');\n errorEl.className = 'forms-expert-error-message';\n errorEl.textContent = error;\n group.appendChild(errorEl);\n }\n return group;\n }\n\n case 'currency': {\n input = document.createElement('input');\n input.type = 'number';\n input.className = addCustomClass('forms-expert-input', styling?.fieldClassName);\n input.value = String(value ?? '');\n if (field.min !== undefined) input.min = String(field.min);\n if (field.max !== undefined) input.max = String(field.max);\n input.step = String(field.step || 0.01);\n break;\n }\n\n case 'phone':\n input = document.createElement('input');\n input.type = 'tel';\n input.className = addCustomClass('forms-expert-input', styling?.fieldClassName);\n input.value = String(value || '');\n break;\n\n case 'url':\n input = document.createElement('input');\n input.type = 'url';\n input.className = addCustomClass('forms-expert-input', styling?.fieldClassName);\n input.value = String(value || '');\n break;\n\n case 'password':\n input = document.createElement('input');\n input.type = 'password';\n input.className = addCustomClass('forms-expert-input', styling?.fieldClassName);\n input.value = String(value || '');\n break;\n\n case 'time':\n input = document.createElement('input');\n input.type = 'time';\n input.className = addCustomClass('forms-expert-input', styling?.fieldClassName);\n input.value = String(value || '');\n break;\n\n case 'datetime':\n input = document.createElement('input');\n input.type = 'datetime-local';\n input.className = addCustomClass('forms-expert-input', styling?.fieldClassName);\n input.value = String(value || '');\n break;\n\n case 'colorPicker':\n input = document.createElement('input');\n input.type = 'color';\n input.className = 'forms-expert-color';\n input.value = String(value || '#000000');\n break;\n\n case 'dateRange': {\n // Two date inputs\n const rangeContainer = document.createElement('div');\n rangeContainer.className = 'forms-expert-date-range';\n const range = (value as { start?: string; end?: string }) || {};\n const startInput = document.createElement('input');\n startInput.type = 'date';\n startInput.className = addCustomClass('forms-expert-input', styling?.fieldClassName);\n startInput.name = `${field.name}.start`;\n startInput.value = range.start || '';\n const endInput = document.createElement('input');\n endInput.type = 'date';\n endInput.className = addCustomClass('forms-expert-input', styling?.fieldClassName);\n endInput.name = `${field.name}.end`;\n endInput.value = range.end || '';\n rangeContainer.appendChild(startInput);\n rangeContainer.appendChild(endInput);\n wrapper.appendChild(rangeContainer);\n if (error) {\n const errorEl = document.createElement('div');\n errorEl.className = 'forms-expert-error-message';\n errorEl.textContent = error;\n wrapper.appendChild(errorEl);\n }\n group.appendChild(wrapper);\n return group;\n }\n\n case 'address': {\n const addrContainer = document.createElement('div');\n addrContainer.className = 'forms-expert-address';\n const addrFields = field.addressFields || ['street', 'city', 'state', 'zip', 'country'];\n const addr = (value as Record<string, string>) || {};\n const labels: Record<string, string> = { street: 'Street', street2: 'Street Line 2', city: 'City', state: 'State', zip: 'ZIP', country: 'Country' };\n addrFields.forEach((af) => {\n const inp = document.createElement('input');\n inp.type = 'text';\n inp.className = addCustomClass('forms-expert-input', styling?.fieldClassName);\n inp.name = `${field.name}.${af}`;\n inp.placeholder = labels[af] || af;\n inp.value = addr[af] || '';\n addrContainer.appendChild(inp);\n });\n wrapper.appendChild(addrContainer);\n if (error) {\n const errorEl = document.createElement('div');\n errorEl.className = 'forms-expert-error-message';\n errorEl.textContent = error;\n wrapper.appendChild(errorEl);\n }\n group.appendChild(wrapper);\n return group;\n }\n\n case 'name': {\n const nameContainer = document.createElement('div');\n nameContainer.className = 'forms-expert-name';\n const nameFields = field.nameFields || ['first', 'last'];\n const nameVal = (value as Record<string, string>) || {};\n const labels: Record<string, string> = { prefix: 'Prefix', first: 'First Name', middle: 'Middle', last: 'Last Name', suffix: 'Suffix' };\n nameFields.forEach((nf) => {\n const inp = document.createElement('input');\n inp.type = 'text';\n inp.className = addCustomClass('forms-expert-input', styling?.fieldClassName);\n inp.name = `${field.name}.${nf}`;\n inp.placeholder = labels[nf] || nf;\n inp.value = nameVal[nf] || '';\n nameContainer.appendChild(inp);\n });\n wrapper.appendChild(nameContainer);\n if (error) {\n const errorEl = document.createElement('div');\n errorEl.className = 'forms-expert-error-message';\n errorEl.textContent = error;\n wrapper.appendChild(errorEl);\n }\n group.appendChild(wrapper);\n return group;\n }\n\n case 'imageChoice': {\n const imgContainer = document.createElement('div');\n imgContainer.className = 'forms-expert-image-choice';\n const opts = (field.options || []) as Array<{ label: string; value: string; imageUrl?: string }>;\n const selected = value as string;\n opts.forEach((opt) => {\n const card = document.createElement('button');\n card.type = 'button';\n card.className = `forms-expert-image-choice-item ${selected === opt.value ? 'active' : ''}`;\n card.dataset.value = opt.value;\n if (opt.imageUrl) {\n const img = document.createElement('img');\n img.src = opt.imageUrl;\n img.alt = opt.label;\n card.appendChild(img);\n }\n const lbl = document.createElement('span');\n lbl.textContent = opt.label;\n card.appendChild(lbl);\n imgContainer.appendChild(card);\n });\n wrapper.appendChild(imgContainer);\n if (error) {\n const errorEl = document.createElement('div');\n errorEl.className = 'forms-expert-error-message';\n errorEl.textContent = error;\n wrapper.appendChild(errorEl);\n }\n group.appendChild(wrapper);\n return group;\n }\n\n case 'ranking': {\n const rankContainer = document.createElement('div');\n rankContainer.className = 'forms-expert-ranking';\n const opts = (field.options || []) as string[];\n const ranked = (value as string[]) || [...opts];\n ranked.forEach((item, i) => {\n const row = document.createElement('div');\n row.className = 'forms-expert-ranking-item';\n row.textContent = `${i + 1}. ${item}`;\n row.dataset.value = item;\n rankContainer.appendChild(row);\n });\n wrapper.appendChild(rankContainer);\n if (error) {\n const errorEl = document.createElement('div');\n errorEl.className = 'forms-expert-error-message';\n errorEl.textContent = error;\n wrapper.appendChild(errorEl);\n }\n group.appendChild(wrapper);\n return group;\n }\n\n case 'location': {\n const locContainer = document.createElement('div');\n locContainer.className = 'forms-expert-location';\n const loc = (value as { lat?: number; lng?: number; address?: string }) || {};\n const addrInput = document.createElement('input');\n addrInput.type = 'text';\n addrInput.className = addCustomClass('forms-expert-input', styling?.fieldClassName);\n addrInput.name = `${field.name}.address`;\n addrInput.placeholder = 'Address';\n addrInput.value = loc.address || '';\n locContainer.appendChild(addrInput);\n const coordRow = document.createElement('div');\n coordRow.className = 'forms-expert-location-coords';\n const latInput = document.createElement('input');\n latInput.type = 'number';\n latInput.className = addCustomClass('forms-expert-input', styling?.fieldClassName);\n latInput.name = `${field.name}.lat`;\n latInput.placeholder = 'Latitude';\n latInput.step = 'any';\n latInput.value = loc.lat !== undefined ? String(loc.lat) : '';\n const lngInput = document.createElement('input');\n lngInput.type = 'number';\n lngInput.className = addCustomClass('forms-expert-input', styling?.fieldClassName);\n lngInput.name = `${field.name}.lng`;\n lngInput.placeholder = 'Longitude';\n lngInput.step = 'any';\n lngInput.value = loc.lng !== undefined ? String(loc.lng) : '';\n coordRow.appendChild(latInput);\n coordRow.appendChild(lngInput);\n locContainer.appendChild(coordRow);\n wrapper.appendChild(locContainer);\n if (error) {\n const errorEl = document.createElement('div');\n errorEl.className = 'forms-expert-error-message';\n errorEl.textContent = error;\n wrapper.appendChild(errorEl);\n }\n group.appendChild(wrapper);\n return group;\n }\n\n default:\n input = document.createElement('input');\n input.type = field.type === 'email' ? 'email' : field.type === 'number' ? 'number' : field.type === 'date' ? 'date' : 'text';\n input.className = addCustomClass('forms-expert-input', styling?.fieldClassName);\n input.value = String(value || '');\n if (field.type === 'number') {\n if (field.min !== undefined) input.min = String(field.min);\n if (field.max !== undefined) input.max = String(field.max);\n if (field.step !== undefined) input.step = String(field.step);\n }\n break;\n }\n \n input!.id = `mira-field-${field.name}`;\n input!.name = field.name;\n if (field.placeholder && 'placeholder' in input!) {\n (input as HTMLInputElement | HTMLTextAreaElement).placeholder = field.placeholder;\n }\n if (field.required) input!.required = true;\n \n if (error) {\n input!.classList.add('forms-expert-error');\n }\n \n wrapper.appendChild(input!);\n \n // Error message\n if (error) {\n const errorEl = document.createElement('div');\n errorEl.className = 'forms-expert-error-message';\n errorEl.textContent = error;\n wrapper.appendChild(errorEl);\n }\n \n group.appendChild(wrapper);\n \n return group;\n}\n\n/**\n * Render the entire form\n */\nexport function renderForm(\n schema: FormSchema,\n values: Record<string, unknown> = {},\n errors: Record<string, string> = {},\n options: {\n honeypot?: boolean;\n showBranding?: boolean;\n brandingText?: string;\n brandingUrl?: string;\n submitText?: string;\n isLoading?: boolean;\n hideRequiredAsterisk?: boolean;\n formName?: string;\n showFormName?: boolean;\n secondaryButton?: SecondaryButton;\n buttonAlign?: string;\n buttonClassName?: string;\n formNameFontSize?: number;\n formNameFontWeight?: 'normal' | 'medium' | 'semibold' | 'bold';\n } = {}\n): HTMLFormElement {\n const form = document.createElement('form');\n form.className = 'forms-expert';\n \n // Hide required asterisks via CSS if configured\n if (options.hideRequiredAsterisk) {\n const style = document.createElement('style');\n style.textContent = '.forms-expert .forms-expert-required { display: none; }';\n form.appendChild(style);\n }\n\n // Form name\n if (options.showFormName !== false && options.formName) {\n const title = document.createElement('h1');\n title.className = 'forms-expert-title';\n title.textContent = options.formName;\n title.style.fontSize = options.formNameFontSize != null ? `${options.formNameFontSize}px` : '1.5rem';\n const weightMap: Record<string, string> = { normal: '400', medium: '500', semibold: '600', bold: '700' };\n title.style.fontWeight = weightMap[options.formNameFontWeight || 'bold'] || '700';\n title.style.marginBottom = '0.5rem';\n form.appendChild(title);\n }\n \n // Render fields with row grouping\n const styling = schema.styling;\n const fields = schema.fields;\n const isInlineBtn = styling?.buttonAlign === 'inline';\n const fieldsContainer = document.createElement('div');\n if (isInlineBtn) { fieldsContainer.style.flex = '1 1 0'; fieldsContainer.style.minWidth = '180px'; }\n let i = 0;\n while (i < fields.length) {\n const field = fields[i];\n if (field.row != null) {\n const rowFields: FormField[] = [field];\n let j = i + 1;\n while (j < fields.length && fields[j].row === field.row) {\n rowFields.push(fields[j]);\n j++;\n }\n if (rowFields.length > 1) {\n const rowDiv = document.createElement('div');\n rowDiv.style.display = 'flex';\n rowDiv.style.gap = '0.75rem';\n rowDiv.style.flexWrap = 'wrap';\n rowFields.forEach((f) => {\n const wrapper = document.createElement('div');\n const wp = getWidthPercent(f.width);\n if (wp) {\n wrapper.style.flex = `0 0 calc(${wp} - 0.75rem)`;\n } else {\n wrapper.style.flex = '1 1 0';\n }\n wrapper.style.minWidth = '180px';\n const fieldEl = renderField(f, values[f.name], errors[f.name], styling);\n wrapper.appendChild(fieldEl);\n rowDiv.appendChild(wrapper);\n });\n fieldsContainer.appendChild(rowDiv);\n } else {\n const fieldEl = renderField(field, values[field.name], errors[field.name], styling);\n fieldsContainer.appendChild(fieldEl);\n }\n i = j;\n } else {\n const fieldEl = renderField(field, values[field.name], errors[field.name], styling);\n fieldsContainer.appendChild(fieldEl);\n i++;\n }\n }\n form.appendChild(fieldsContainer);\n \n // Honeypot\n if (options.honeypot) {\n const honeypot = document.createElement('input');\n honeypot.type = 'text';\n honeypot.name = '_hp';\n honeypot.className = 'forms-expert-honeypot';\n honeypot.tabIndex = -1;\n honeypot.autocomplete = 'off';\n form.appendChild(honeypot);\n }\n \n // Hidden page URL\n const pageUrl = document.createElement('input');\n pageUrl.type = 'hidden';\n pageUrl.name = 'pageUrl';\n pageUrl.value = typeof window !== 'undefined' ? window.location.href : '';\n form.appendChild(pageUrl);\n \n // Button wrapper\n const btnWrapper = document.createElement('div');\n btnWrapper.className = 'forms-expert-button-wrapper';\n\n // Submit button\n const button = document.createElement('button');\n button.type = 'submit';\n button.className = addCustomClass('forms-expert-button', options.buttonClassName);\n button.disabled = options.isLoading || false;\n \n if (options.isLoading) {\n button.innerHTML = `\n <span class=\"forms-expert-button-loading\">\n <span class=\"forms-expert-spinner\"></span>\n Submitting...\n </span>\n `;\n } else {\n const btnIcon = styling?.buttonIcon;\n const btnIconPos = styling?.buttonIconPosition || 'left';\n if (btnIcon) {\n button.style.display = 'inline-flex';\n button.style.alignItems = 'center';\n button.style.gap = '0.5rem';\n const iconSpan = document.createElement('span');\n iconSpan.style.display = 'inline-flex';\n iconSpan.style.flexShrink = '0';\n iconSpan.innerHTML = btnIcon;\n const textSpan = document.createElement('span');\n textSpan.textContent = options.submitText || 'Submit';\n if (btnIconPos === 'right') {\n button.appendChild(textSpan);\n button.appendChild(iconSpan);\n } else {\n button.appendChild(iconSpan);\n button.appendChild(textSpan);\n }\n } else {\n button.textContent = options.submitText || 'Submit';\n }\n }\n\n // Secondary button helper\n const sec = options.secondaryButton;\n const createSecondaryLink = (): HTMLAnchorElement | null => {\n if (!sec?.enabled) return null;\n const a = document.createElement('a');\n a.className = 'forms-expert-secondary-btn';\n a.href = sec.href || '#';\n a.style.display = 'inline-flex';\n a.style.alignItems = 'center';\n a.style.gap = '0.5rem';\n if (sec.icon) {\n const iconSpan = document.createElement('span');\n iconSpan.style.display = 'inline-flex';\n iconSpan.style.flexShrink = '0';\n iconSpan.innerHTML = sec.icon;\n const textSpan = document.createElement('span');\n textSpan.textContent = sec.text || 'Learn More';\n if (sec.iconPosition === 'right') {\n a.appendChild(textSpan);\n a.appendChild(iconSpan);\n } else {\n a.appendChild(iconSpan);\n a.appendChild(textSpan);\n }\n } else {\n a.textContent = sec.text || 'Learn More';\n }\n if (sec.openInNewTab) { a.target = '_blank'; a.rel = 'noopener noreferrer'; }\n const btnColor = styling?.primaryColor || '#3b82f6';\n const secColor = sec.color || btnColor;\n if (sec.style === 'filled') {\n a.style.background = secColor;\n a.style.color = sec.textColor || '#ffffff';\n a.style.border = 'none';\n } else if (sec.style === 'outlined') {\n a.style.background = 'transparent';\n a.style.color = sec.textColor || secColor;\n a.style.border = `2px solid ${secColor}`;\n } else if (sec.style === 'link') {\n a.style.background = 'transparent';\n a.style.color = sec.textColor || secColor;\n a.style.border = 'none';\n a.style.textDecoration = 'underline';\n } else {\n a.style.background = 'transparent';\n a.style.color = sec.textColor || secColor;\n a.style.border = 'none';\n }\n if (sec.marginTop != null) a.style.marginTop = `${sec.marginTop}px`;\n if (sec.marginBottom != null) a.style.marginBottom = `${sec.marginBottom}px`;\n if (sec.fontSize != null) a.style.fontSize = `${sec.fontSize}px`;\n return a;\n };\n\n // Inline secondary button (left)\n if (sec?.enabled && sec.position === 'left') {\n const link = createSecondaryLink();\n if (link) btnWrapper.appendChild(link);\n }\n\n btnWrapper.appendChild(button);\n\n // Inline secondary button (right or default)\n if (sec?.enabled && sec.position !== 'left' && sec.position !== 'below') {\n const link = createSecondaryLink();\n if (link) {\n link.style.marginLeft = 'auto';\n btnWrapper.appendChild(link);\n }\n }\n\n if (isInlineBtn) {\n btnWrapper.style.marginTop = '0';\n // Re-parent: remove fieldsContainer from form, put both in inline wrapper\n form.removeChild(fieldsContainer);\n const inlineWrapper = document.createElement('div');\n inlineWrapper.style.display = 'flex';\n inlineWrapper.style.alignItems = 'flex-end';\n inlineWrapper.style.gap = '0.75rem';\n inlineWrapper.style.flexWrap = 'wrap';\n inlineWrapper.appendChild(fieldsContainer);\n inlineWrapper.appendChild(btnWrapper);\n form.appendChild(inlineWrapper);\n } else {\n form.appendChild(btnWrapper);\n }\n\n // Secondary button (below)\n if (sec?.enabled && sec.position === 'below') {\n const belowDiv = document.createElement('div');\n belowDiv.className = 'forms-expert-secondary-below';\n const secAlign = sec.align || options.buttonAlign || 'left';\n belowDiv.style.justifyContent = secAlign === 'center' ? 'center' : secAlign === 'right' ? 'flex-end' : 'flex-start';\n if (sec.marginTop != null) belowDiv.style.marginTop = `${sec.marginTop}px`;\n if (sec.marginBottom != null) belowDiv.style.marginBottom = `${sec.marginBottom}px`;\n const link = createSecondaryLink();\n if (link) {\n link.style.marginTop = '0';\n link.style.marginBottom = '0';\n belowDiv.appendChild(link);\n }\n form.appendChild(belowDiv);\n }\n \n // Branding\n if (options.showBranding !== false) {\n const brandingText = options.brandingText || 'Powered by Forms Expert';\n const brandingUrl = options.brandingUrl || 'https://mira.io';\n const branding = document.createElement('div');\n branding.className = 'forms-expert-branding';\n branding.innerHTML = `<a href=\"${brandingUrl}\" target=\"_blank\" rel=\"noopener\">${brandingText}</a>`;\n form.appendChild(branding);\n }\n \n return form;\n}\n\n/**\n * Render success message\n */\nexport function renderSuccess(message: string): HTMLElement {\n const container = document.createElement('div');\n container.className = 'forms-expert-success';\n \n container.innerHTML = `\n <svg class=\"forms-expert-success-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M5 13l4 4L19 7\"></path>\n </svg>\n <div class=\"forms-expert-success-message\">${escapeHtml(message)}</div>\n `;\n \n return container;\n}\n\n/**\n * Convert validation errors array to record\n */\nexport function errorsToRecord(errors: ValidationError[]): Record<string, string> {\n return errors.reduce(\n (acc, err) => ({ ...acc, [err.field]: err.message }),\n {}\n );\n}\n","/**\n * Form field types\n */\nexport type BasicFieldType =\n | 'text' | 'email' | 'number' | 'textarea' | 'select'\n | 'checkbox' | 'file' | 'date' | 'hidden';\n\nexport type InteractiveFieldType =\n | 'radio' | 'multiselect' | 'rating' | 'scale' | 'toggle'\n | 'ranking' | 'imageChoice' | 'phone' | 'url' | 'password'\n | 'richText' | 'slider' | 'currency' | 'time' | 'datetime'\n | 'dateRange' | 'address' | 'name' | 'dropdown' | 'colorPicker'\n | 'location' | 'opinionScale' | 'consent';\n\nexport type LayoutFieldType = 'heading' | 'divider' | 'paragraph';\n\nexport type FormFieldType = BasicFieldType | InteractiveFieldType | LayoutFieldType;\n\nexport interface FormFieldOption {\n label: string;\n value: string;\n imageUrl?: string;\n}\n\n/**\n * Form field definition\n */\nexport interface FormField {\n name: string;\n type: FormFieldType;\n label?: string;\n placeholder?: string;\n required?: boolean;\n options?: string[] | FormFieldOption[];\n defaultValue?: unknown;\n maxFileSize?: number;\n allowedMimeTypes?: string[];\n multiple?: boolean;\n min?: number;\n max?: number;\n step?: number;\n ratingMax?: number;\n lowLabel?: string;\n highLabel?: string;\n defaultCountryCode?: string;\n currencyCode?: string;\n currencySymbol?: string;\n addressFields?: ('street' | 'street2' | 'city' | 'state' | 'zip' | 'country')[];\n nameFields?: ('prefix' | 'first' | 'middle' | 'last' | 'suffix')[];\n content?: string;\n paragraphFontSize?: number;\n consentText?: string;\n consentUrl?: string;\n consentFontSize?: number;\n maxLength?: number;\n stepId?: string;\n visibleWhen?: {\n field: string;\n operator: 'eq' | 'neq' | 'contains' | 'gt' | 'lt';\n value: unknown;\n };\n\n // Row layout\n row?: number;\n width?: '1/4' | '1/3' | '1/2' | '2/3' | '3/4' | 'full';\n}\n\n/**\n * Secondary button configuration\n */\nexport interface SecondaryButton {\n enabled: boolean;\n text: string;\n href: string;\n openInNewTab?: boolean;\n position?: 'left' | 'right' | 'below';\n align?: 'left' | 'center' | 'right';\n marginTop?: number;\n marginBottom?: number;\n style?: 'filled' | 'outlined' | 'minimal' | 'link';\n color?: string;\n textColor?: string;\n fontSize?: number;\n icon?: string;\n iconPosition?: 'left' | 'right';\n}\n\n/**\n * Form styling configuration\n */\nexport interface FormStyling {\n theme: 'light' | 'dark' | 'system' | 'custom';\n primaryColor: string;\n backgroundColor: string;\n textColor: string;\n errorColor?: string;\n successColor?: string;\n borderRadius: 'none' | 'sm' | 'md' | 'lg';\n fontSize: 'sm' | 'md' | 'lg' | 'small' | 'medium' | 'large';\n buttonStyle: 'filled' | 'outline' | 'outlined' | 'minimal';\n labelPosition: 'top' | 'left' | 'floating';\n labelClassName?: string;\n fieldClassName?: string;\n buttonClassName?: string;\n customCss?: string;\n // Extended styling (matching hosted form builder)\n fontFamily?: string;\n formWidth?: 'narrow' | 'medium' | 'wide' | 'full';\n fieldLayout?: 'stacked' | 'inline';\n fieldBorderStyle?: 'full' | 'bottom';\n fieldBorderColor?: string;\n fieldBorderRadius?: 'none' | 'small' | 'medium' | 'large' | 'full';\n fieldPaddingX?: number;\n fieldPaddingY?: number;\n separatorColor?: string;\n buttonColor?: string;\n buttonText?: string;\n buttonRadius?: 'none' | 'small' | 'medium' | 'large' | 'full';\n buttonAlign?: 'left' | 'center' | 'right' | 'inline';\n buttonSize?: 'small' | 'medium' | 'large';\n buttonPaddingX?: number;\n buttonPaddingY?: number;\n buttonGradient?: string;\n buttonFullWidth?: boolean;\n buttonFontSize?: number;\n buttonIcon?: string;\n buttonIconPosition?: 'left' | 'right';\n fieldSpacing?: 'compact' | 'normal' | 'relaxed' | 'spacious';\n formPadding?: 'none' | 'compact' | 'normal' | 'relaxed' | 'spacious';\n labelSpacing?: 'compact' | 'normal' | 'relaxed';\n placeholderFontSize?: 'small' | 'medium' | 'large';\n headingSize?: 'small' | 'medium' | 'large' | 'extra-large';\n paragraphSize?: 'small' | 'medium' | 'large';\n formNameFontSize?: number;\n formNameFontWeight?: 'normal' | 'medium' | 'semibold' | 'bold';\n hideRequiredAsterisk?: boolean;\n logoUrl?: string;\n logoPosition?: 'top-left' | 'top-center' | 'top-right';\n coverImageUrl?: string;\n backgroundImageUrl?: string;\n backgroundOverlay?: number;\n transparentBackground?: boolean;\n secondaryButton?: SecondaryButton;\n // Input styling\n inputBackgroundColor?: string;\n placeholderColor?: string;\n}\n\n/**\n * Form schema\n */\nexport interface FormSchema {\n fields: FormField[];\n styling?: FormStyling;\n}\n\n/**\n * Form captcha settings\n */\nexport interface CaptchaSettings {\n enabled: boolean;\n provider?: 'turnstile' | 'recaptcha' | 'hcaptcha';\n siteKey?: string;\n}\n\n/**\n * Form branding configuration\n */\nexport interface FormBranding {\n enabled: boolean;\n text?: string;\n url?: string;\n}\n\n/**\n * Form status response from API\n */\nexport interface FormStatusResponse {\n active: boolean;\n formId?: string;\n name?: string;\n description?: string | null;\n mode?: 'free' | 'schema';\n type?: 'hosted' | 'embed' | 'both';\n layout?: 'single' | 'multi-step';\n schema?: FormSchema;\n steps?: Array<{ title: string; description?: string; fields: string[] }>;\n /** Top-level styling (full hosted styling config) */\n styling?: FormStyling;\n embedConfig?: {\n width?: string;\n height?: string;\n maxHeight?: string;\n minHeight?: string;\n autoResize?: boolean;\n transparentBackground?: boolean;\n [key: string]: unknown;\n };\n error?: string;\n /** Captcha settings (top-level) */\n captcha?: CaptchaSettings;\n settings?: {\n /** @deprecated Use top-level captcha instead */\n captcha?: CaptchaSettings;\n honeypot: boolean;\n allowAttachments: boolean;\n maxAttachments?: number;\n maxAttachmentSize?: number;\n successMessage?: string;\n redirectUrl?: string;\n showFormName?: boolean;\n };\n /** Access control configuration */\n accessControl?: {\n mode: string;\n passwordProtected: boolean;\n };\n /** Branding configuration */\n branding?: FormBranding;\n /** Hosted config (page settings, success page, etc.) */\n hostedConfig?: {\n pageTitle?: string;\n successMessage?: string;\n successPageType?: 'message' | 'redirect' | 'custom';\n redirectUrl?: string;\n customSuccessHtml?: string;\n [key: string]: unknown;\n };\n closesAt?: string | null;\n resourceId?: string;\n /** Available published translation language codes */\n availableLanguages?: string[];\n /** Current language applied to this response (null if base language) */\n currentLanguage?: string | null;\n /** Whether to show language switch UI */\n showLanguageSwitch?: boolean;\n}\n\n/**\n * Validation error\n */\nexport interface ValidationError {\n field: string;\n message: string;\n}\n\n/**\n * Validation response from API\n */\nexport interface ValidationResponse {\n valid: boolean;\n errors: ValidationError[];\n}\n\n/**\n * Submission response from API\n */\nexport interface SubmissionResponse {\n success: boolean;\n submissionId: string;\n message: string;\n}\n\n/**\n * Submit options\n */\nexport interface SubmitOptions {\n pageUrl?: string;\n captchaToken?: string;\n /** Callback for upload progress */\n onProgress?: (progress: UploadProgress) => void;\n}\n\n/**\n * Upload progress information\n */\nexport interface UploadProgress {\n loaded: number;\n total: number;\n percentage: number;\n}\n\n/**\n * File validation error\n */\nexport interface FileValidationError {\n field: string;\n file: string;\n error: 'size' | 'type' | 'count';\n message: string;\n}\n\n/**\n * SDK configuration\n */\nexport interface FormsSDKConfig {\n apiKey: string;\n resourceId: string;\n baseUrl?: string;\n}\n\n/**\n * Form handler options\n */\nexport interface FormHandlerOptions {\n /** Track form views for analytics (completion rate) */\n trackViews?: boolean;\n onSubmitStart?: () => void;\n onSubmitSuccess?: (response: SubmissionResponse) => void;\n onSubmitError?: (error: FormsError) => void;\n onValidationError?: (errors: ValidationError[]) => void;\n}\n\n/**\n * Forms SDK error\n */\nexport class FormsError extends Error {\n constructor(\n message: string,\n public code: string,\n public statusCode: number,\n public retryAfter?: number\n ) {\n super(message);\n this.name = 'FormsError';\n }\n}\n\n/**\n * Validation error class\n */\nexport class FormValidationError extends Error {\n constructor(public errors: ValidationError[]) {\n super('Validation failed');\n this.name = 'FormValidationError';\n }\n}\n","import {\n FormsSDKConfig,\n FormStatusResponse,\n ValidationResponse,\n SubmissionResponse,\n SubmitOptions,\n FormsError,\n UploadProgress,\n} from './types';\n\n/**\n * API client for forms backend\n */\nexport class FormsApiClient {\n private baseUrl: string;\n private apiKey: string;\n private resourceId: string;\n\n constructor(config: FormsSDKConfig) {\n this.apiKey = config.apiKey;\n this.resourceId = config.resourceId;\n this.baseUrl = (config.baseUrl || 'https://api.forms.expert/api/v1').replace(/\\/$/, '');\n }\n\n /**\n * Build URL with token query parameter\n */\n private buildUrl(path: string): string {\n const separator = path.includes('?') ? '&' : '?';\n return `${this.baseUrl}${path}${separator}token=${encodeURIComponent(this.apiKey)}`;\n }\n\n /**\n * Make an API request\n */\n private async request<T>(\n method: string,\n path: string,\n body?: object\n ): Promise<T> {\n const url = this.buildUrl(path);\n\n const response = await fetch(url, {\n method,\n headers: {\n 'Content-Type': 'application/json',\n },\n body: body ? JSON.stringify(body) : undefined,\n });\n\n const data = await response.json();\n\n if (!response.ok) {\n throw new FormsError(\n data.message || 'Request failed',\n data.code || 'UNKNOWN_ERROR',\n response.status,\n data.retryAfter\n );\n }\n\n return data;\n }\n\n /**\n * Check if form is active and get configuration\n */\n async isActive(slug: string, lang?: string): Promise<FormStatusResponse> {\n const langParam = lang ? `?lang=${encodeURIComponent(lang)}` : '';\n return this.request('GET', `/f/${this.resourceId}/${slug}/is-active${langParam}`);\n }\n\n /**\n * Validate form data without submitting\n */\n async validate(\n slug: string,\n data: Record<string, unknown>\n ): Promise<ValidationResponse> {\n return this.request('POST', `/f/${this.resourceId}/${slug}/validate`, {\n data,\n });\n }\n\n /**\n * Submit form data (supports files)\n */\n async submit(\n slug: string,\n data: Record<string, unknown>,\n options?: SubmitOptions\n ): Promise<SubmissionResponse> {\n const url = this.buildUrl(`/f/${this.resourceId}/${slug}`);\n \n // Check if data contains files\n const hasFiles = Object.values(data).some(\n (v) => v instanceof File || (v instanceof FileList && v.length > 0)\n );\n\n if (hasFiles || options?.onProgress) {\n // Use FormData and XMLHttpRequest for file uploads with progress\n return this.submitWithFormData(url, data, options);\n }\n\n // Use regular JSON request for non-file submissions\n return this.request('POST', `/f/${this.resourceId}/${slug}`, {\n data,\n pageUrl: options?.pageUrl || (typeof window !== 'undefined' ? window.location.href : undefined),\n captchaToken: options?.captchaToken,\n });\n }\n\n /**\n * Submit with FormData (for file uploads with progress tracking)\n */\n private submitWithFormData(\n url: string,\n data: Record<string, unknown>,\n options?: SubmitOptions\n ): Promise<SubmissionResponse> {\n return new Promise((resolve, reject) => {\n const formData = new FormData();\n\n // Add data fields\n for (const [key, value] of Object.entries(data)) {\n if (value instanceof File) {\n formData.append(key, value);\n } else if (value instanceof FileList) {\n Array.from(value).forEach((file) => formData.append(key, file));\n } else if (value !== undefined && value !== null) {\n formData.append(`data[${key}]`, String(value));\n }\n }\n\n // Add metadata\n const pageUrl = options?.pageUrl || (typeof window !== 'undefined' ? window.location.href : '');\n if (pageUrl) {\n formData.append('pageUrl', pageUrl);\n }\n if (options?.captchaToken) {\n formData.append('captchaToken', options.captchaToken);\n }\n\n const xhr = new XMLHttpRequest();\n\n // Progress tracking\n if (options?.onProgress) {\n xhr.upload.addEventListener('progress', (event) => {\n if (event.lengthComputable) {\n options.onProgress!({\n loaded: event.loaded,\n total: event.total,\n percentage: Math.round((event.loaded / event.total) * 100),\n });\n }\n });\n }\n\n xhr.addEventListener('load', () => {\n try {\n const response = JSON.parse(xhr.responseText);\n if (xhr.status >= 200 && xhr.status < 300) {\n resolve(response);\n } else {\n reject(new FormsError(\n response.message || 'Submission failed',\n response.code || 'UNKNOWN_ERROR',\n xhr.status,\n response.retryAfter\n ));\n }\n } catch {\n reject(new FormsError('Invalid response', 'PARSE_ERROR', xhr.status));\n }\n });\n\n xhr.addEventListener('error', () => {\n reject(new FormsError('Network error', 'NETWORK_ERROR', 0));\n });\n\n xhr.addEventListener('abort', () => {\n reject(new FormsError('Request aborted', 'ABORTED', 0));\n });\n\n xhr.open('POST', url);\n xhr.send(formData);\n });\n }\n\n /**\n * Track a form view (for analytics completion rate)\n */\n async trackView(slug: string): Promise<void> {\n const url = this.buildUrl(`/f/${this.resourceId}/${slug}/view`);\n await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: '{}' }).catch(() => {});\n }\n\n /**\n * Get resource ID\n */\n getResourceId(): string {\n return this.resourceId;\n }\n\n /**\n * Get base URL\n */\n getBaseUrl(): string {\n return this.baseUrl;\n }\n}\n","import { FormsApiClient } from './api-client';\nimport {\n FormsSDKConfig,\n FormStatusResponse,\n ValidationResponse,\n SubmissionResponse,\n SubmitOptions,\n FormHandlerOptions,\n FormsError,\n FormValidationError,\n} from './types';\n\n/**\n * Form handler for a specific form\n */\nexport class FormHandler {\n private apiClient: FormsApiClient;\n private slug: string;\n private config: FormStatusResponse | null = null;\n private options: FormHandlerOptions;\n\n constructor(\n apiClient: FormsApiClient,\n slug: string,\n options: FormHandlerOptions = {}\n ) {\n this.apiClient = apiClient;\n this.slug = slug;\n this.options = options;\n }\n\n /**\n * Initialize form handler and fetch configuration\n */\n async initialize(lang?: string): Promise<FormStatusResponse> {\n this.config = await this.apiClient.isActive(this.slug, lang);\n if (this.options.trackViews) {\n this.apiClient.trackView(this.slug);\n }\n return this.config;\n }\n\n /**\n * Get cached form configuration\n */\n getConfig(): FormStatusResponse | null {\n return this.config;\n }\n\n /**\n * Check if form is active\n */\n isActive(): boolean {\n return this.config?.active ?? false;\n }\n\n /**\n * Check if captcha is required\n */\n requiresCaptcha(): boolean {\n return this.config?.settings?.captcha?.enabled ?? false;\n }\n\n /**\n * Get captcha provider\n */\n getCaptchaProvider(): 'turnstile' | 'recaptcha' | 'hcaptcha' | undefined {\n return this.config?.settings?.captcha?.provider;\n }\n\n /**\n * Get form schema\n */\n getSchema() {\n return this.config?.schema;\n }\n\n /**\n * Validate form data\n */\n async validate(data: Record<string, unknown>): Promise<ValidationResponse> {\n return this.apiClient.validate(this.slug, data);\n }\n\n /**\n * Submit form data\n */\n async submit(\n data: Record<string, unknown>,\n options?: SubmitOptions\n ): Promise<SubmissionResponse> {\n this.options.onSubmitStart?.();\n\n try {\n // Validate first if in schema mode\n if (this.config?.mode === 'schema') {\n const validation = await this.validate(data);\n if (!validation.valid) {\n this.options.onValidationError?.(validation.errors);\n throw new FormValidationError(validation.errors);\n }\n }\n\n const response = await this.apiClient.submit(this.slug, data, options);\n this.options.onSubmitSuccess?.(response);\n return response;\n } catch (error) {\n if (error instanceof FormsError) {\n this.options.onSubmitError?.(error);\n }\n throw error;\n }\n }\n\n /**\n * Get success message from config\n */\n getSuccessMessage(): string {\n return this.config?.settings?.successMessage || 'Form submitted successfully!';\n }\n\n /**\n * Get redirect URL from config\n */\n getRedirectUrl(): string | undefined {\n return this.config?.settings?.redirectUrl;\n }\n}\n\n/**\n * Main Forms SDK class\n */\nexport class FormsSDK {\n private apiClient: FormsApiClient;\n\n constructor(config: FormsSDKConfig) {\n this.apiClient = new FormsApiClient(config);\n }\n\n /**\n * Check if form is active and get configuration\n */\n async isActive(slug: string, lang?: string): Promise<FormStatusResponse> {\n return this.apiClient.isActive(slug, lang);\n }\n\n /**\n * Validate form data without submitting\n */\n async validate(\n slug: string,\n data: Record<string, unknown>\n ): Promise<ValidationResponse> {\n return this.apiClient.validate(slug, data);\n }\n\n /**\n * Submit form data\n */\n async submit(\n slug: string,\n data: Record<string, unknown>,\n options?: SubmitOptions\n ): Promise<SubmissionResponse> {\n return this.apiClient.submit(slug, data, options);\n }\n\n /**\n * Create a form handler for a specific form\n */\n form(slug: string, options?: FormHandlerOptions): FormHandler {\n return new FormHandler(this.apiClient, slug, options);\n }\n\n /**\n * Track a form view (for analytics completion rate)\n */\n async trackView(slug: string): Promise<void> {\n return this.apiClient.trackView(slug);\n }\n\n /**\n * Submit with retry logic for rate limits\n */\n async submitWithRetry(\n slug: string,\n data: Record<string, unknown>,\n options?: SubmitOptions & { maxRetries?: number }\n ): Promise<SubmissionResponse> {\n const maxRetries = options?.maxRetries ?? 3;\n let lastError: Error | null = null;\n\n for (let attempt = 0; attempt < maxRetries; attempt++) {\n try {\n return await this.submit(slug, data, options);\n } catch (error) {\n lastError = error as Error;\n\n if (error instanceof FormsError) {\n // Don't retry validation or auth errors\n if (\n [\n 'VALIDATION_ERROR',\n 'CAPTCHA_REQUIRED',\n 'ORIGIN_NOT_ALLOWED',\n ].includes(error.code)\n ) {\n throw error;\n }\n\n // Retry rate limits with backoff\n if (error.code.includes('RATE_LIMIT')) {\n const retryAfter = error.retryAfter || Math.pow(2, attempt) * 1000;\n await new Promise((resolve) => setTimeout(resolve, retryAfter));\n continue;\n }\n }\n\n // Exponential backoff for network errors\n await new Promise((resolve) =>\n setTimeout(resolve, Math.pow(2, attempt) * 1000)\n );\n }\n }\n\n throw lastError!;\n }\n}\n","import {\n FormsSDK,\n FormsSDKConfig,\n FormStatusResponse,\n FormStyling,\n SubmissionResponse,\n ValidationError,\n FormValidationError,\n FormsError,\n} from '../core';\nimport { generateFormStyles } from './styles';\nimport { renderForm, renderSuccess, errorsToRecord } from './renderer';\n\nexport interface FormWidgetOptions {\n /** Target element or selector */\n target: string | HTMLElement;\n /** Form slug */\n slug: string;\n /** Track form views for analytics (completion rate). Default: false */\n trackViews?: boolean;\n /** Custom submit button text */\n submitText?: string;\n /** Success callback */\n onSuccess?: (response: SubmissionResponse) => void;\n /** Error callback */\n onError?: (error: Error) => void;\n /** Validation error callback */\n onValidationError?: (errors: ValidationError[]) => void;\n /** Reset form after submission */\n resetOnSuccess?: boolean;\n /** Redirect after success (overrides form config) */\n redirectUrl?: string;\n /** Language code to pass to backend */\n lang?: string;\n}\n\n/**\n * Form widget for embedding forms\n */\nexport class FormWidget {\n private sdk: FormsSDK;\n private container: HTMLElement;\n private config: FormStatusResponse | null = null;\n private values: Record<string, unknown> = {};\n private errors: Record<string, string> = {};\n private isLoading = false;\n private isSubmitted = false;\n private options: FormWidgetOptions;\n private styleEl: HTMLStyleElement | null = null;\n\n constructor(sdkConfig: FormsSDKConfig, options: FormWidgetOptions) {\n this.sdk = new FormsSDK(sdkConfig);\n this.options = options;\n\n // Get container element\n const target = options.target;\n if (typeof target === 'string') {\n const el = document.querySelector(target);\n if (!el) throw new Error(`Element not found: ${target}`);\n this.container = el as HTMLElement;\n } else {\n this.container = target;\n }\n }\n\n /**\n * Initialize and render the form\n */\n async init(): Promise<void> {\n try {\n this.renderLoading();\n this.config = await this.sdk.isActive(this.options.slug, this.options.lang);\n\n if (!this.config.active) {\n this.renderError('This form is not available');\n return;\n }\n\n if (this.options.trackViews) {\n this.sdk.trackView(this.options.slug);\n }\n\n this.injectStyles();\n this.render();\n } catch (error) {\n this.renderError('Failed to load form');\n this.options.onError?.(error as Error);\n }\n }\n\n /**\n * Inject CSS styles\n */\n private injectStyles(): void {\n if (this.styleEl) return;\n\n this.styleEl = document.createElement('style');\n this.styleEl.id = `forms-expert-styles-${this.options.slug}`;\n const mergedStyling = { ...this.config?.schema?.styling, ...this.config?.styling } as FormStyling | undefined;\n this.styleEl.textContent = generateFormStyles(mergedStyling);\n document.head.appendChild(this.styleEl);\n\n // Load Google Font if needed\n this.injectGoogleFont(mergedStyling?.fontFamily);\n }\n\n /**\n * Inject Google Font stylesheet if needed\n */\n private injectGoogleFont(fontFamily?: string): void {\n if (!fontFamily) return;\n \n const googleFonts = ['Inter', 'Roboto', 'Open Sans', 'Lato', 'Poppins', 'Montserrat', 'Nunito', 'Source Sans Pro', 'Raleway', 'Ubuntu', 'Playfair Display', 'Merriweather'];\n const fontToLoad = fontFamily.split(',')[0]?.trim();\n \n if (!fontToLoad || !googleFonts.includes(fontToLoad)) return;\n \n const linkId = `forms-expert-font-${this.options.slug}`;\n if (document.getElementById(linkId)) return;\n \n const link = document.createElement('link');\n link.id = linkId;\n link.rel = 'stylesheet';\n link.href = `https://fonts.googleapis.com/css2?family=${fontToLoad.replace(/ /g, '+')}:wght@400;500;600;700&display=swap`;\n document.head.appendChild(link);\n }\n\n /**\n * Render the form\n */\n private render(): void {\n if (!this.config?.schema) return;\n\n if (this.isSubmitted) {\n this.container.innerHTML = '';\n const successMessage =\n this.config.settings?.successMessage || 'Form submitted successfully!';\n this.container.appendChild(renderSuccess(successMessage));\n return;\n }\n\n const mergedStyling = { ...this.config.schema.styling, ...this.config.styling } as FormStyling;\n const schemaWithStyling = { ...this.config.schema, styling: mergedStyling };\n\n const form = renderForm(schemaWithStyling, this.values, this.errors, {\n honeypot: this.config.settings?.honeypot,\n showBranding: this.config.branding?.enabled !== false,\n brandingText: this.config.branding?.text,\n brandingUrl: this.config.branding?.url,\n submitText: mergedStyling.buttonText || this.options.submitText,\n isLoading: this.isLoading,\n hideRequiredAsterisk: mergedStyling.hideRequiredAsterisk,\n formName: this.config.hostedConfig?.pageTitle as string || this.config.name,\n showFormName: this.config.settings?.showFormName as boolean | undefined,\n secondaryButton: mergedStyling.secondaryButton,\n buttonAlign: mergedStyling.buttonAlign,\n buttonClassName: mergedStyling.buttonClassName,\n formNameFontSize: mergedStyling.formNameFontSize,\n formNameFontWeight: mergedStyling.formNameFontWeight,\n });\n\n // Handle input changes\n form.addEventListener('input', (e) => {\n const target = e.target as HTMLInputElement;\n if (target.name && target.name !== '_hp' && target.name !== 'pageUrl') {\n if (target.type === 'checkbox') {\n this.values[target.name] = target.checked;\n } else if (target.type === 'file') {\n // Store FileList for multiple files, single File for single uploads\n this.values[target.name] = target.multiple ? target.files : target.files?.[0];\n } else {\n this.values[target.name] = target.value;\n }\n // Clear error on change\n if (this.errors[target.name]) {\n delete this.errors[target.name];\n this.render();\n }\n }\n });\n\n // Handle submit\n form.addEventListener('submit', (e) => {\n e.preventDefault();\n this.handleSubmit();\n });\n\n this.container.innerHTML = '';\n this.container.appendChild(form);\n }\n\n /**\n * Handle form submission\n */\n private async handleSubmit(): Promise<void> {\n if (this.isLoading || !this.config) return;\n\n this.isLoading = true;\n this.errors = {};\n this.render();\n\n try {\n const response = await this.sdk.submit(this.options.slug, this.values);\n\n this.isLoading = false;\n this.isSubmitted = true;\n this.render();\n\n this.options.onSuccess?.(response);\n\n // Handle redirect\n const redirectUrl =\n this.options.redirectUrl || this.config.settings?.redirectUrl;\n if (redirectUrl) {\n setTimeout(() => {\n window.location.href = redirectUrl;\n }, 1500);\n }\n\n // Reset form after delay if configured\n if (this.options.resetOnSuccess) {\n setTimeout(() => {\n this.reset();\n }, 3000);\n }\n } catch (error) {\n this.isLoading = false;\n\n if (error instanceof FormValidationError) {\n this.errors = errorsToRecord(error.errors);\n this.options.onValidationError?.(error.errors);\n } else {\n this.options.onError?.(error as Error);\n }\n\n this.render();\n }\n }\n\n /**\n * Reset form to initial state\n */\n reset(): void {\n this.values = {};\n this.errors = {};\n this.isLoading = false;\n this.isSubmitted = false;\n this.render();\n }\n\n /**\n * Render loading spinner\n */\n private renderLoading(): void {\n this.container.innerHTML = `\n <div class=\"forms-expert\" style=\"display: flex; align-items: center; justify-content: center; padding: 2rem;\">\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" style=\"animation: fe-spin 1s linear infinite; color: #9ca3af;\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"3\" fill=\"none\" stroke-dasharray=\"31.4 31.4\" stroke-linecap=\"round\"/>\n </svg>\n </div>\n <style>@keyframes fe-spin { to { transform: rotate(360deg); } }</style>\n `;\n }\n\n /**\n * Render error message\n */\n private renderError(message: string): void {\n this.container.innerHTML = `\n <div class=\"forms-expert\" style=\"text-align: center; padding: 2rem; color: #ef4444;\">\n <p>${message}</p>\n </div>\n `;\n }\n\n /**\n * Destroy widget\n */\n destroy(): void {\n this.container.innerHTML = '';\n this.styleEl?.remove();\n this.styleEl = null;\n }\n}\n\n/**\n * Auto-initialize forms on page load\n */\nexport function autoInit(): void {\n const forms = document.querySelectorAll('[data-forms-expert]');\n\n forms.forEach((el) => {\n const apiKey = el.getAttribute('data-api-key');\n const resourceId = el.getAttribute('data-resource-id');\n const slug = el.getAttribute('data-forms-expert');\n const baseUrl = el.getAttribute('data-base-url') || undefined;\n\n if (!apiKey || !resourceId || !slug) {\n console.error('Forms Expert: Missing required attributes', {\n apiKey: !!apiKey,\n resourceId: !!resourceId,\n slug: !!slug,\n });\n return;\n }\n\n const widget = new FormWidget(\n { apiKey, resourceId, baseUrl },\n {\n target: el as HTMLElement,\n slug,\n trackViews: el.getAttribute('data-track-views') === 'true',\n submitText: el.getAttribute('data-submit-text') || undefined,\n resetOnSuccess: el.getAttribute('data-reset') === 'true',\n lang: el.getAttribute('data-lang') || undefined,\n }\n );\n\n widget.init();\n });\n}\n\n// Auto-init on DOMContentLoaded\nif (typeof window !== 'undefined') {\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', autoInit);\n } else {\n autoInit();\n }\n}\n"],"mappings":"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","names":["defaultStyling","getBorderRadius","radius","getFieldBorderRadius","getButtonRadius","getFontSize","size","getPlaceholderFontSize","getFieldSpacing","spacing","getFormPadding","padding","getLabelSpacing","getFormWidth","width","getButtonAlign","align","generateFormStyles","styling","s","fieldRadius","btnRadius","fontSize","phFontSize","fieldSpacing","formPadding","labelSpacing","formWidth","btnBgColor","btnTextColor","borderColor","separatorColor","fontFamily","btnAlign","btnSize","btnPx","btnPy","btnFs","btnBg","escapeHtml","text","div","getHeadingSizePx","size","getParagraphSizePx","addCustomClass","baseClass","customClass","normalizeOpts","options","o","getWidthPercent","width","renderField","field","value","error","styling","group","h","p","hr","pFontSize","div","input","wrapper","label","text","escapeHtml","link","errorEl","selectWrapper","selectBtn","opts","selectedOpt","labelSpan","arrow","dropdown","opt","item","e","hiddenInput","el","radioGroup","radioWrapper","radioInput","checkGroup","selected","checkWrapper","checkInput","ratingContainer","max","current","i","star","scaleContainer","min","btn","labels","borderColor","mutedColor","primaryColor","dropzone","fileInput","icon","types","sizeInfo","s","rangeContainer","range","startInput","endInput","addrContainer","addrFields","addr","af","inp","nameContainer","nameFields","nameVal","nf","imgContainer","card","img","lbl","rankContainer","row","locContainer","loc","addrInput","coordRow","latInput","lngInput","renderForm","schema","values","errors","form","style","title","weightMap","fields","isInlineBtn","fieldsContainer","rowFields","j","rowDiv","f","wp","fieldEl","honeypot","pageUrl","btnWrapper","button","btnIcon","btnIconPos","iconSpan","textSpan","sec","createSecondaryLink","a","btnColor","secColor","inlineWrapper","belowDiv","secAlign","brandingText","brandingUrl","branding","renderSuccess","message","container","errorsToRecord","acc","err","FormsError","message","code","statusCode","retryAfter","FormValidationError","errors","FormsApiClient","config","path","separator","method","body","url","response","data","FormsError","slug","lang","langParam","options","v","resolve","reject","formData","key","value","file","pageUrl","xhr","event","FormHandler","apiClient","slug","options","lang","data","validation","FormValidationError","response","error","FormsError","FormsSDK","config","FormsApiClient","maxRetries","lastError","attempt","retryAfter","resolve","FormWidget","sdkConfig","options","FormsSDK","target","el","error","mergedStyling","generateFormStyles","fontFamily","googleFonts","fontToLoad","linkId","link","successMessage","renderSuccess","schemaWithStyling","form","renderForm","e","response","redirectUrl","FormValidationError","errorsToRecord","message","autoInit","apiKey","resourceId","slug","baseUrl"]}