@nextlyhq/plugin-form-builder 0.0.1
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.
- package/LICENSE +22 -0
- package/README.md +122 -0
- package/dist/CheckboxFieldEditor-K4T6QX52.js +121 -0
- package/dist/CheckboxFieldEditor-K4T6QX52.js.map +1 -0
- package/dist/DateFieldEditor-JFJFAVOH.js +187 -0
- package/dist/DateFieldEditor-JFJFAVOH.js.map +1 -0
- package/dist/EmailFieldEditor-MMOXXL7P.js +138 -0
- package/dist/EmailFieldEditor-MMOXXL7P.js.map +1 -0
- package/dist/NumberFieldEditor-UISAYR6Z.js +175 -0
- package/dist/NumberFieldEditor-UISAYR6Z.js.map +1 -0
- package/dist/RadioFieldEditor-6UQFH4WT.js +165 -0
- package/dist/RadioFieldEditor-6UQFH4WT.js.map +1 -0
- package/dist/SelectFieldEditor-PSO4KHV4.js +213 -0
- package/dist/SelectFieldEditor-PSO4KHV4.js.map +1 -0
- package/dist/TextFieldEditor-5EU64EA5.js +187 -0
- package/dist/TextFieldEditor-5EU64EA5.js.map +1 -0
- package/dist/TextareaFieldEditor-773G3LNM.js +190 -0
- package/dist/TextareaFieldEditor-773G3LNM.js.map +1 -0
- package/dist/admin/index.css +934 -0
- package/dist/admin/index.css.map +1 -0
- package/dist/admin/index.d.ts +547 -0
- package/dist/admin/index.js +4030 -0
- package/dist/admin/index.js.map +1 -0
- package/dist/chunk-ABNZFTQK.js +586 -0
- package/dist/chunk-ABNZFTQK.js.map +1 -0
- package/dist/chunk-XTCEPJ7B.js +256 -0
- package/dist/chunk-XTCEPJ7B.js.map +1 -0
- package/dist/components/index.d.ts +3 -0
- package/dist/components/index.js +9 -0
- package/dist/components/index.js.map +1 -0
- package/dist/index-C0kBvYjm.d.ts +1012 -0
- package/dist/index.d.ts +1663 -0
- package/dist/index.js +2470 -0
- package/dist/index.js.map +1 -0
- package/dist/styles/form-builder.css +1150 -0
- package/dist/styles/submissions-filter.css +75 -0
- package/package.json +96 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/styles/form-builder.css"],"sourcesContent":["/**\n * Form Builder Styles\n *\n * Styles for the visual drag-and-drop form builder UI.\n * Layout is now driven by Tailwind utility classes in:\n * - FormBuilderView.tsx (page layout, header, sidebar shell, main tabs)\n * - FieldLibrary.tsx (accordion palette)\n * - FormCanvas.tsx (field rows, empty state)\n *\n * This file retains only:\n * 1. CSS custom properties + dark mode overrides\n * 2. FieldEditor component styles (.field-editor-*)\n * 3. FormSettingsTab component styles (.form-settings-*)\n * 4. FormNotificationsTab component styles (.form-notifications-*, .form-notification-*)\n * 5. Integration modal / card styles (.form-integration-*)\n *\n * @module styles/form-builder\n * @since 0.1.0\n */\n\n/* ============================================================================\n CSS Custom Properties\n ============================================================================ */\n\n.form-builder-view {\n --fb-primary: hsl(var(--primary));\n --fb-primary-hover: hsl(var(--primary) / 0.9);\n --fb-primary-light: hsl(var(--primary) / 0.1);\n --fb-danger: #ef4444;\n --fb-danger-hover: #dc2626;\n --fb-success: #22c55e;\n --fb-warning: #f59e0b;\n\n --fb-bg: #ffffff;\n --fb-bg-muted: #f8fafc;\n --fb-bg-hover: #f1f5f9;\n --fb-border: #e2e8f0;\n --fb-border-focus: hsl(var(--primary));\n\n --fb-text: #1e293b;\n --fb-text-muted: #64748b;\n --fb-text-light: #94a3b8;\n\n --fb-radius-sm: 0.375rem; /* 6px */\n --fb-radius-md: 0.375rem; /* 6px */\n --fb-radius-lg: 0.375rem; /* 6px */\n\n --fb-shadow: none;\n --fb-shadow-md: none;\n --fb-shadow-lg: none;\n}\n\n/* ============================================================================\n Dark Mode Overrides\n ============================================================================ */\n\n.dark .form-builder-view,\n[data-theme=\"dark\"] .form-builder-view {\n --fb-bg: hsl(222.2, 47.4%, 11.2%);\n --fb-bg-muted: hsl(217.2, 32.6%, 17.5%);\n --fb-bg-hover: hsl(215.4, 16.3%, 25.9%);\n --fb-border: hsl(217.2, 32.6%, 17.5%);\n\n --fb-text: hsl(210, 40%, 98%);\n --fb-text-muted: hsl(215, 20.2%, 65.1%);\n --fb-text-light: hsl(215.3, 25%, 36.7%);\n}\n\n/* ============================================================================\n Field Editor (Right Panel)\n ============================================================================ */\n\n.field-editor {\n padding: 16px;\n}\n\n.field-editor-header {\n margin-bottom: 20px;\n}\n\n.field-editor-title {\n font-size: 0.875rem;\n font-weight: 600;\n color: var(--fb-text);\n margin: 0 0 4px 0;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.field-editor-type-badge {\n font-size: 0.75rem;\n font-weight: 500;\n color: var(--fb-primary);\n background: var(--fb-primary-light);\n padding: 2px 8px;\n border-radius: 9999px;\n}\n\n.field-editor-actions {\n display: flex;\n gap: 8px;\n margin-top: 12px;\n}\n\n.field-editor-action-btn {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n font-size: 0.75rem;\n font-weight: 500;\n border: 1px solid var(--fb-border);\n border-radius: var(--fb-radius-sm);\n background: var(--fb-bg);\n cursor: pointer;\n transition: all 0.15s ease;\n color: var(--fb-text-muted);\n}\n\n.field-editor-action-btn:hover {\n border-color: var(--fb-text-light);\n color: var(--fb-text);\n}\n\n.field-editor-action-btn--danger:hover {\n border-color: var(--fb-danger);\n color: var(--fb-danger);\n background: #fef2f2;\n}\n\n.field-editor-section {\n margin-bottom: 20px;\n}\n\n.field-editor-section-title {\n font-size: 0.75rem;\n font-weight: 600;\n color: var(--fb-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n margin: 0 0 12px 0;\n}\n\n.field-editor-row {\n margin-bottom: 14px;\n}\n\n.field-editor-row:last-child {\n margin-bottom: 0;\n}\n\n.field-editor-row--checkbox {\n display: flex;\n align-items: center;\n}\n\n.field-editor-field {\n margin-bottom: 16px;\n}\n\n.field-editor-field:last-child {\n margin-bottom: 0;\n}\n\n.field-editor-label {\n display: block;\n font-size: 0.8125rem;\n font-weight: 500;\n color: var(--fb-text);\n margin-bottom: 6px;\n}\n\n.field-editor-input {\n width: 100%;\n padding: 8px 12px;\n font-size: 0.875rem;\n color: var(--fb-text);\n background: var(--fb-bg);\n border: 1px solid var(--fb-border);\n border-radius: var(--fb-radius-sm);\n transition: all 0.15s ease;\n}\n\n.field-editor-input:focus {\n outline: none;\n border-color: var(--fb-border-focus);\n}\n\n.field-editor-input::placeholder {\n color: var(--fb-text-light);\n}\n\n.field-editor-input--small {\n width: 120px;\n}\n\n.field-editor-textarea {\n min-height: 80px;\n resize: vertical;\n}\n\n.field-editor-select {\n width: 100%;\n padding: 8px 12px;\n font-size: 0.875rem;\n color: var(--fb-text);\n background: var(--fb-bg);\n border: 1px solid var(--fb-border);\n border-radius: var(--fb-radius-sm);\n transition: all 0.15s ease;\n cursor: pointer;\n}\n\n.field-editor-select:focus {\n outline: none;\n border-color: var(--fb-border-focus);\n}\n\n.field-editor-checkbox-row {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.field-editor-checkbox {\n width: 16px;\n height: 16px;\n accent-color: var(--fb-primary);\n}\n\n.field-editor-checkbox-label {\n display: flex;\n align-items: center;\n gap: 8px;\n cursor: pointer;\n font-size: 0.8125rem;\n color: var(--fb-text);\n}\n\n.field-editor-help {\n display: block;\n font-size: 0.6875rem;\n color: var(--fb-text-muted);\n margin-top: 4px;\n}\n\n.field-editor-warning {\n display: block;\n font-size: 0.6875rem;\n color: var(--fb-warning);\n margin-top: 4px;\n}\n\n.field-editor-info {\n padding: 10px 14px;\n background: var(--fb-bg-muted);\n border-radius: var(--fb-radius-sm);\n font-size: 0.8125rem;\n color: var(--fb-text-muted);\n}\n\n.field-editor-options {\n margin-bottom: 14px;\n}\n\n.field-editor-options-empty {\n padding: 12px;\n background: var(--fb-bg-muted);\n border-radius: var(--fb-radius-sm);\n font-size: 0.8125rem;\n color: var(--fb-text-muted);\n text-align: center;\n margin-bottom: 8px;\n}\n\n.field-editor-options-list {\n display: flex;\n flex-direction: column;\n gap: 6px;\n margin-bottom: 8px;\n}\n\n.field-editor-option-row {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.field-editor-option-remove {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 24px;\n background: none;\n border: 1px solid var(--fb-border);\n border-radius: var(--fb-radius-sm);\n cursor: pointer;\n font-size: 1rem;\n color: var(--fb-text-muted);\n transition: all 0.15s ease;\n flex-shrink: 0;\n}\n\n.field-editor-option-remove:hover {\n color: var(--fb-danger);\n border-color: var(--fb-danger);\n background: #fef2f2;\n}\n\n.field-editor-add-option-btn {\n padding: 6px 12px;\n font-size: 0.75rem;\n font-weight: 500;\n color: var(--fb-primary);\n background: var(--fb-primary-light);\n border: 1px dashed var(--fb-primary);\n border-radius: var(--fb-radius-sm);\n cursor: pointer;\n transition: all 0.15s ease;\n width: 100%;\n}\n\n.field-editor-add-option-btn:hover {\n background: #dbeafe;\n}\n\n.field-editor-tabs {\n display: flex;\n gap: 0;\n background: var(--fb-bg-muted);\n border-radius: var(--fb-radius-sm);\n padding: 3px;\n margin-bottom: 16px;\n}\n\n.field-editor-tab {\n flex: 1;\n padding: 5px 10px;\n font-size: 0.75rem;\n font-weight: 500;\n color: var(--fb-text-muted);\n background: transparent;\n border: none;\n border-radius: 4px;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.field-editor-tab--active {\n color: var(--fb-text);\n background: var(--fb-bg);\n}\n\n.field-editor-footer {\n display: flex;\n gap: 8px;\n margin-top: 20px;\n padding-top: 16px;\n border-top: 1px solid var(--fb-border);\n}\n\n.field-editor-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n padding: 7px 14px;\n font-size: 0.8125rem;\n font-weight: 500;\n border-radius: var(--fb-radius-sm);\n cursor: pointer;\n transition: all 0.15s ease;\n border: 1px solid var(--fb-border);\n background: var(--fb-bg);\n color: var(--fb-text-muted);\n}\n\n.field-editor-btn:hover {\n color: var(--fb-text);\n border-color: var(--fb-text-light);\n}\n\n.field-editor-btn--secondary {\n color: var(--fb-text-muted);\n}\n\n.field-editor-btn--danger {\n color: var(--fb-danger);\n border-color: #fecaca;\n background: #fef2f2;\n}\n\n.field-editor-btn--danger:hover {\n background: #fee2e2;\n border-color: var(--fb-danger);\n}\n\n/* ============================================================================\n Form Settings Tab\n ============================================================================ */\n\n.form-settings-tab {\n max-width: 640px;\n}\n\n.form-settings-section {\n margin-bottom: 32px;\n padding-bottom: 24px;\n border-bottom: 1px solid var(--fb-border);\n}\n\n.form-settings-section:last-child {\n margin-bottom: 0;\n padding-bottom: 0;\n border-bottom: none;\n}\n\n.form-settings-section-title {\n font-size: 1rem;\n font-weight: 600;\n color: var(--fb-text);\n margin: 0 0 16px 0;\n}\n\n.form-settings-field {\n margin-bottom: 16px;\n}\n\n.form-settings-field:last-child {\n margin-bottom: 0;\n}\n\n.form-settings-field--checkbox {\n margin-bottom: 12px;\n}\n\n.form-settings-label {\n display: block;\n font-size: 0.875rem;\n font-weight: 500;\n color: var(--fb-text);\n margin-bottom: 6px;\n}\n\n.form-settings-input,\n.form-settings-textarea {\n width: 100%;\n padding: 10px 14px;\n font-size: 0.875rem;\n color: var(--fb-text);\n background: var(--fb-bg);\n border: 1px solid var(--fb-border);\n border-radius: var(--fb-radius-md);\n transition: all 0.15s ease;\n}\n\n.form-settings-input:focus,\n.form-settings-textarea:focus {\n outline: none;\n border-color: var(--fb-border-focus);\n}\n\n.form-settings-input::placeholder,\n.form-settings-textarea::placeholder {\n color: var(--fb-text-light);\n}\n\n.form-settings-textarea {\n min-height: 80px;\n resize: vertical;\n}\n\n.form-settings-checkbox-label {\n display: flex;\n align-items: center;\n gap: 10px;\n cursor: pointer;\n font-size: 0.875rem;\n color: var(--fb-text);\n}\n\n.form-settings-checkbox {\n width: 18px;\n height: 18px;\n accent-color: var(--fb-primary);\n cursor: pointer;\n}\n\n.form-settings-hint {\n font-size: 0.75rem;\n color: var(--fb-text-muted);\n margin: 6px 0 0 0;\n}\n\n.form-settings-field--checkbox .form-settings-hint {\n margin-left: 28px;\n}\n\n/* ============================================================================\n Form Notifications Tab\n ============================================================================ */\n\n.form-notifications-tab {\n max-width: 800px;\n}\n\n.form-notifications-header {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: 24px;\n margin-bottom: 24px;\n}\n\n.form-notifications-header-content {\n flex: 1;\n}\n\n.form-notifications-title {\n font-size: 1.125rem;\n font-weight: 600;\n color: var(--fb-text);\n margin: 0 0 4px 0;\n}\n\n.form-notifications-description {\n font-size: 0.875rem;\n color: var(--fb-text-muted);\n margin: 0;\n}\n\n.form-notifications-actions {\n display: flex;\n gap: 8px;\n}\n\n.form-notifications-add-btn {\n padding: 8px 14px;\n font-size: 0.8125rem;\n font-weight: 500;\n color: #ffffff;\n background: var(--fb-primary);\n border: none;\n border-radius: var(--fb-radius-md);\n cursor: pointer;\n transition: all 0.15s ease;\n white-space: nowrap;\n}\n\n.form-notifications-add-btn:hover {\n background: var(--fb-primary-hover);\n}\n\n.form-notifications-add-btn--secondary {\n color: var(--fb-text);\n background: var(--fb-bg);\n border: 1px solid var(--fb-border);\n}\n\n.form-notifications-add-btn--secondary:hover {\n background: var(--fb-bg-hover);\n border-color: var(--fb-text-light);\n}\n\n/* Empty State */\n.form-notifications-empty {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 48px 24px;\n background: var(--fb-bg-muted);\n border: 2px dashed var(--fb-border);\n border-radius: var(--fb-radius-lg);\n text-align: center;\n}\n\n.form-notifications-empty-icon {\n font-size: 3rem;\n margin-bottom: 16px;\n opacity: 0.5;\n}\n\n.form-notifications-empty-title {\n font-size: 1rem;\n font-weight: 600;\n color: var(--fb-text);\n margin: 0 0 8px 0;\n}\n\n.form-notifications-empty-hint {\n font-size: 0.875rem;\n color: var(--fb-text-muted);\n margin: 0 0 20px 0;\n max-width: 400px;\n}\n\n.form-notifications-empty-actions {\n display: flex;\n gap: 8px;\n}\n\n/* Notifications List */\n.form-notifications-list {\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n\n/* Notification Card */\n.form-notification-card {\n background: var(--fb-bg);\n border: 1px solid var(--fb-border);\n border-radius: var(--fb-radius-lg);\n overflow: hidden;\n}\n\n.form-notification-card--disabled {\n opacity: 0.6;\n}\n\n.form-notification-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n padding: 12px 16px;\n background: var(--fb-bg-muted);\n border-bottom: 1px solid var(--fb-border);\n}\n\n.form-notification-header-left {\n display: flex;\n align-items: center;\n gap: 12px;\n flex: 1;\n min-width: 0;\n}\n\n/* Toggle Switch */\n.form-notification-toggle {\n position: relative;\n display: inline-block;\n width: 40px;\n height: 22px;\n flex-shrink: 0;\n}\n\n.form-notification-toggle input {\n opacity: 0;\n width: 0;\n height: 0;\n}\n\n.form-notification-toggle-slider {\n position: absolute;\n cursor: pointer;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background-color: var(--fb-border);\n transition: 0.2s;\n border-radius: 22px;\n}\n\n.form-notification-toggle-slider:before {\n position: absolute;\n content: \"\";\n height: 16px;\n width: 16px;\n left: 3px;\n bottom: 3px;\n background-color: white;\n transition: 0.2s;\n border-radius: 50%;\n}\n\n.form-notification-toggle input:checked + .form-notification-toggle-slider {\n background-color: var(--fb-success);\n}\n\n.form-notification-toggle\n input:checked\n + .form-notification-toggle-slider:before {\n transform: translateX(18px);\n}\n\n.form-notification-name {\n flex: 1;\n min-width: 0;\n padding: 6px 10px;\n font-size: 0.875rem;\n font-weight: 500;\n color: var(--fb-text);\n background: var(--fb-bg);\n border: 1px solid transparent;\n border-radius: var(--fb-radius-sm);\n transition: all 0.15s ease;\n}\n\n.form-notification-name:focus {\n outline: none;\n border-color: var(--fb-border-focus);\n}\n\n.form-notification-badge {\n padding: 3px 8px;\n font-size: 0.6875rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n border-radius: 9999px;\n flex-shrink: 0;\n}\n\n.form-notification-badge--admin {\n color: #7c3aed;\n background: #ede9fe;\n}\n\n.form-notification-badge--autoReply {\n color: #059669;\n background: #d1fae5;\n}\n\n.form-notification-delete {\n padding: 6px 12px;\n font-size: 0.75rem;\n font-weight: 500;\n color: var(--fb-text-muted);\n background: transparent;\n border: 1px solid var(--fb-border);\n border-radius: var(--fb-radius-sm);\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.form-notification-delete:hover {\n color: var(--fb-danger);\n border-color: var(--fb-danger);\n background: #fef2f2;\n}\n\n.form-notification-body {\n padding: 16px;\n}\n\n.form-notification-row {\n margin-bottom: 16px;\n}\n\n.form-notification-row:last-child {\n margin-bottom: 0;\n}\n\n.form-notification-row--two-col {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 16px;\n}\n\n.form-notification-field {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.form-notification-label {\n font-size: 0.8125rem;\n font-weight: 500;\n color: var(--fb-text);\n}\n\n.form-notification-input,\n.form-notification-textarea {\n padding: 10px 14px;\n font-size: 0.875rem;\n color: var(--fb-text);\n background: var(--fb-bg);\n border: 1px solid var(--fb-border);\n border-radius: var(--fb-radius-md);\n transition: all 0.15s ease;\n}\n\n.form-notification-input:focus,\n.form-notification-textarea:focus {\n outline: none;\n border-color: var(--fb-border-focus);\n}\n\n.form-notification-input::placeholder,\n.form-notification-textarea::placeholder {\n color: var(--fb-text-light);\n}\n\n.form-notification-textarea {\n min-height: 120px;\n resize: vertical;\n font-family: inherit;\n}\n\n.form-notification-hint {\n font-size: 0.75rem;\n color: var(--fb-text-muted);\n}\n\n.form-notification-hint p {\n margin: 0 0 4px 0;\n}\n\n.form-notification-placeholders {\n margin: 0;\n padding-left: 16px;\n list-style: none;\n}\n\n.form-notification-placeholders li {\n margin-bottom: 2px;\n}\n\n.form-notification-placeholders code {\n font-size: 0.6875rem;\n color: var(--fb-primary);\n background: var(--fb-primary-light);\n padding: 1px 4px;\n border-radius: 3px;\n}\n\n/* Help Section */\n.form-notifications-help {\n margin-top: 32px;\n padding: 16px 20px;\n background: var(--fb-bg-muted);\n border-radius: var(--fb-radius-md);\n}\n\n.form-notifications-help h4 {\n font-size: 0.875rem;\n font-weight: 600;\n color: var(--fb-text);\n margin: 0 0 12px 0;\n}\n\n.form-notifications-help ul {\n margin: 0;\n padding-left: 20px;\n font-size: 0.8125rem;\n color: var(--fb-text-muted);\n line-height: 1.6;\n}\n\n.form-notifications-help li {\n margin-bottom: 6px;\n}\n\n.form-notifications-help li:last-child {\n margin-bottom: 0;\n}\n\n.form-notifications-help strong {\n color: var(--fb-text);\n}\n\n/* ============================================================================\n Email Integration Cards\n ============================================================================ */\n\n.form-integration-card {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 16px;\n padding: 14px 16px;\n background: var(--fb-bg);\n border: 1px solid var(--fb-border);\n border-radius: var(--fb-radius-lg);\n transition: border-color 0.15s ease;\n}\n\n.form-integration-card:hover {\n border-color: var(--fb-text-light);\n}\n\n.form-integration-card--disabled {\n opacity: 0.55;\n}\n\n.form-integration-card-left {\n display: flex;\n align-items: center;\n gap: 12px;\n flex: 1;\n min-width: 0;\n}\n\n.form-integration-card-info {\n display: flex;\n flex-direction: column;\n gap: 4px;\n min-width: 0;\n}\n\n.form-integration-card-name {\n font-size: 0.9375rem;\n font-weight: 600;\n color: var(--fb-text);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.form-integration-provider-badge {\n font-size: 0.75rem;\n color: var(--fb-text-muted);\n}\n\n.form-integration-card-actions {\n display: flex;\n gap: 8px;\n flex-shrink: 0;\n}\n\n.form-integration-btn {\n padding: 6px 12px;\n font-size: 0.75rem;\n font-weight: 500;\n border-radius: var(--fb-radius-sm);\n cursor: pointer;\n transition: all 0.15s ease;\n border: 1px solid var(--fb-border);\n background: transparent;\n}\n\n.form-integration-btn--edit {\n color: var(--fb-text-muted);\n}\n\n.form-integration-btn--edit:hover {\n color: var(--fb-primary);\n border-color: var(--fb-primary);\n background: var(--fb-primary-light);\n}\n\n.form-integration-btn--delete {\n color: var(--fb-text-muted);\n}\n\n.form-integration-btn--delete:hover {\n color: var(--fb-danger);\n border-color: var(--fb-danger);\n background: #fef2f2;\n}\n\n/* ============================================================================\n Email Integration Modal\n ============================================================================ */\n\n.form-integration-modal-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.45);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n padding: 24px;\n}\n\n.form-integration-modal {\n background: var(--fb-bg);\n border: 1px solid var(--fb-border);\n border-radius: var(--fb-radius-lg);\n width: 100%;\n max-width: 560px;\n max-height: calc(100vh - 48px);\n display: flex;\n flex-direction: column;\n box-shadow:\n 0 20px 60px rgba(0, 0, 0, 0.15),\n 0 4px 16px rgba(0, 0, 0, 0.1);\n}\n\n.form-integration-modal-header {\n padding: 20px 24px 16px;\n border-bottom: 1px solid var(--fb-border);\n flex-shrink: 0;\n}\n\n.form-integration-modal-title {\n font-size: 1.0625rem;\n font-weight: 600;\n color: var(--fb-text);\n margin: 0;\n}\n\n.form-integration-modal-body {\n padding: 20px 24px;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n gap: 16px;\n flex: 1;\n}\n\n.form-integration-modal-footer {\n padding: 16px 24px;\n border-top: 1px solid var(--fb-border);\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n flex-shrink: 0;\n}\n\n/* Modal select */\n.form-integration-select {\n padding: 10px 14px;\n font-size: 0.875rem;\n color: var(--fb-text);\n background: var(--fb-bg);\n border: 1px solid var(--fb-border);\n border-radius: var(--fb-radius-md);\n transition: all 0.15s ease;\n appearance: none;\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%236b7280' d='M6 8L1 3h10z'/%3E%3C/svg%3E\");\n background-repeat: no-repeat;\n background-position: right 12px center;\n padding-right: 36px;\n cursor: pointer;\n}\n\n.form-integration-select:focus {\n outline: none;\n border-color: var(--fb-border-focus);\n box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);\n}\n\n/* Recipient list */\n.form-integration-recipient-list {\n display: flex;\n flex-direction: column;\n gap: 6px;\n margin-bottom: 8px;\n}\n\n.form-integration-recipient-item {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 6px 10px;\n background: var(--fb-bg-muted);\n border: 1px solid var(--fb-border);\n border-radius: var(--fb-radius-sm);\n font-size: 0.8125rem;\n color: var(--fb-text);\n}\n\n.form-integration-recipient-remove {\n background: transparent;\n border: none;\n color: var(--fb-text-light);\n cursor: pointer;\n font-size: 1rem;\n line-height: 1;\n padding: 0 2px;\n transition: color 0.15s ease;\n}\n\n.form-integration-recipient-remove:hover {\n color: var(--fb-danger);\n}\n\n.form-integration-recipient-add {\n display: flex;\n gap: 8px;\n}\n\n.form-integration-recipient-add .form-notification-input {\n flex: 1;\n}\n\n.form-integration-add-recipient-btn {\n padding: 10px 14px;\n font-size: 0.8125rem;\n font-weight: 500;\n color: var(--fb-text);\n background: var(--fb-bg);\n border: 1px solid var(--fb-border);\n border-radius: var(--fb-radius-md);\n cursor: pointer;\n white-space: nowrap;\n transition: all 0.15s ease;\n flex-shrink: 0;\n}\n\n.form-integration-add-recipient-btn:hover {\n background: var(--fb-bg-hover);\n border-color: var(--fb-text-light);\n}\n\n/* Active row */\n.form-integration-active-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 0 4px;\n border-top: 1px solid var(--fb-border);\n}\n\n.form-integration-active-label {\n font-size: 0.875rem;\n font-weight: 500;\n color: var(--fb-text);\n}\n\n/* Modal footer buttons */\n.form-integration-cancel-btn {\n padding: 9px 18px;\n font-size: 0.875rem;\n font-weight: 500;\n color: var(--fb-text);\n background: var(--fb-bg);\n border: 1px solid var(--fb-border);\n border-radius: var(--fb-radius-md);\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.form-integration-cancel-btn:hover {\n background: var(--fb-bg-hover);\n border-color: var(--fb-text-light);\n}\n\n.form-integration-save-btn {\n padding: 9px 18px;\n font-size: 0.875rem;\n font-weight: 500;\n color: #ffffff;\n background: var(--fb-primary);\n border: none;\n border-radius: var(--fb-radius-md);\n cursor: pointer;\n transition: background 0.15s ease;\n}\n\n.form-integration-save-btn:hover {\n background: var(--fb-primary-hover);\n}\n"],"mappings":";AAwBA,CAAC;AACC,gBAAc,IAAI,IAAI;AACtB,sBAAoB,IAAI,IAAI,WAAW,EAAE;AACzC,sBAAoB,IAAI,IAAI,WAAW,EAAE;AACzC,eAAa;AACb,qBAAmB;AACnB,gBAAc;AACd,gBAAc;AAEd,WAAS;AACT,iBAAe;AACf,iBAAe;AACf,eAAa;AACb,qBAAmB,IAAI,IAAI;AAE3B,aAAW;AACX,mBAAiB;AACjB,mBAAiB;AAEjB,kBAAgB;AAChB,kBAAgB;AAChB,kBAAgB;AAEhB,eAAa;AACb,kBAAgB;AAChB,kBAAgB;AAClB;AAMA,CAAC,KAAK,CAhCL;AAiCD,CAAC,iBAAmB,CAjCnB;AAkCC,WAAS,IAAI,KAAK,EAAE,KAAK,EAAE;AAC3B,iBAAe,IAAI,KAAK,EAAE,KAAK,EAAE;AACjC,iBAAe,IAAI,KAAK,EAAE,KAAK,EAAE;AACjC,eAAa,IAAI,KAAK,EAAE,KAAK,EAAE;AAE/B,aAAW,IAAI,GAAG,EAAE,GAAG,EAAE;AACzB,mBAAiB,IAAI,GAAG,EAAE,KAAK,EAAE;AACjC,mBAAiB,IAAI,KAAK,EAAE,GAAG,EAAE;AACnC;AAMA,CAAC;AACC,WAAS;AACX;AAEA,CAAC;AACC,iBAAe;AACjB;AAEA,CAAC;AACC,aAAW;AACX,eAAa;AACb,SAAO,IAAI;AACX,UAAQ,EAAE,EAAE,IAAI;AAChB,WAAS;AACT,eAAa;AACb,OAAK;AACP;AAEA,CAAC;AACC,aAAW;AACX,eAAa;AACb,SAAO,IAAI;AACX,cAAY,IAAI;AAChB,WAAS,IAAI;AACb,iBAAe;AACjB;AAEA,CAAC;AACC,WAAS;AACT,OAAK;AACL,cAAY;AACd;AAEA,CAAC;AACC,WAAS;AACT,eAAa;AACb,OAAK;AACL,WAAS,IAAI;AACb,aAAW;AACX,eAAa;AACb,UAAQ,IAAI,MAAM,IAAI;AACtB,iBAAe,IAAI;AACnB,cAAY,IAAI;AAChB,UAAQ;AACR,cAAY,IAAI,MAAM;AACtB,SAAO,IAAI;AACb;AAEA,CAfC,uBAeuB;AACtB,gBAAc,IAAI;AAClB,SAAO,IAAI;AACb;AAEA,CAAC,+BAA+B;AAC9B,gBAAc,IAAI;AAClB,SAAO,IAAI;AACX,cAAY;AACd;AAEA,CAAC;AACC,iBAAe;AACjB;AAEA,CAAC;AACC,aAAW;AACX,eAAa;AACb,SAAO,IAAI;AACX,kBAAgB;AAChB,kBAAgB;AAChB,UAAQ,EAAE,EAAE,KAAK;AACnB;AAEA,CAAC;AACC,iBAAe;AACjB;AAEA,CAJC,gBAIgB;AACf,iBAAe;AACjB;AAEA,CAAC;AACC,WAAS;AACT,eAAa;AACf;AAEA,CAAC;AACC,iBAAe;AACjB;AAEA,CAJC,kBAIkB;AACjB,iBAAe;AACjB;AAEA,CAAC;AACC,WAAS;AACT,aAAW;AACX,eAAa;AACb,SAAO,IAAI;AACX,iBAAe;AACjB;AAEA,CAAC;AACC,SAAO;AACP,WAAS,IAAI;AACb,aAAW;AACX,SAAO,IAAI;AACX,cAAY,IAAI;AAChB,UAAQ,IAAI,MAAM,IAAI;AACtB,iBAAe,IAAI;AACnB,cAAY,IAAI,MAAM;AACxB;AAEA,CAXC,kBAWkB;AACjB,WAAS;AACT,gBAAc,IAAI;AACpB;AAEA,CAhBC,kBAgBkB;AACjB,SAAO,IAAI;AACb;AAEA,CAAC;AACC,SAAO;AACT;AAEA,CAAC;AACC,cAAY;AACZ,UAAQ;AACV;AAEA,CAAC;AACC,SAAO;AACP,WAAS,IAAI;AACb,aAAW;AACX,SAAO,IAAI;AACX,cAAY,IAAI;AAChB,UAAQ,IAAI,MAAM,IAAI;AACtB,iBAAe,IAAI;AACnB,cAAY,IAAI,MAAM;AACtB,UAAQ;AACV;AAEA,CAZC,mBAYmB;AAClB,WAAS;AACT,gBAAc,IAAI;AACpB;AAEA,CAAC;AACC,WAAS;AACT,eAAa;AACb,OAAK;AACP;AAEA,CAAC;AACC,SAAO;AACP,UAAQ;AACR,gBAAc,IAAI;AACpB;AAEA,CAAC;AACC,WAAS;AACT,eAAa;AACb,OAAK;AACL,UAAQ;AACR,aAAW;AACX,SAAO,IAAI;AACb;AAEA,CAAC;AACC,WAAS;AACT,aAAW;AACX,SAAO,IAAI;AACX,cAAY;AACd;AAEA,CAAC;AACC,WAAS;AACT,aAAW;AACX,SAAO,IAAI;AACX,cAAY;AACd;AAEA,CAAC;AACC,WAAS,KAAK;AACd,cAAY,IAAI;AAChB,iBAAe,IAAI;AACnB,aAAW;AACX,SAAO,IAAI;AACb;AAEA,CAAC;AACC,iBAAe;AACjB;AAEA,CAAC;AACC,WAAS;AACT,cAAY,IAAI;AAChB,iBAAe,IAAI;AACnB,aAAW;AACX,SAAO,IAAI;AACX,cAAY;AACZ,iBAAe;AACjB;AAEA,CAAC;AACC,WAAS;AACT,kBAAgB;AAChB,OAAK;AACL,iBAAe;AACjB;AAEA,CAAC;AACC,WAAS;AACT,eAAa;AACb,OAAK;AACP;AAEA,CAAC;AACC,WAAS;AACT,eAAa;AACb,mBAAiB;AACjB,SAAO;AACP,UAAQ;AACR,cAAY;AACZ,UAAQ,IAAI,MAAM,IAAI;AACtB,iBAAe,IAAI;AACnB,UAAQ;AACR,aAAW;AACX,SAAO,IAAI;AACX,cAAY,IAAI,MAAM;AACtB,eAAa;AACf;AAEA,CAhBC,0BAgB0B;AACzB,SAAO,IAAI;AACX,gBAAc,IAAI;AAClB,cAAY;AACd;AAEA,CAAC;AACC,WAAS,IAAI;AACb,aAAW;AACX,eAAa;AACb,SAAO,IAAI;AACX,cAAY,IAAI;AAChB,UAAQ,IAAI,OAAO,IAAI;AACvB,iBAAe,IAAI;AACnB,UAAQ;AACR,cAAY,IAAI,MAAM;AACtB,SAAO;AACT;AAEA,CAbC,2BAa2B;AAC1B,cAAY;AACd;AAEA,CAAC;AACC,WAAS;AACT,OAAK;AACL,cAAY,IAAI;AAChB,iBAAe,IAAI;AACnB,WAAS;AACT,iBAAe;AACjB;AAEA,CAAC;AACC,QAAM;AACN,WAAS,IAAI;AACb,aAAW;AACX,eAAa;AACb,SAAO,IAAI;AACX,cAAY;AACZ,UAAQ;AACR,iBAAe;AACf,UAAQ;AACR,cAAY,IAAI,MAAM;AACxB;AAEA,CAAC;AACC,SAAO,IAAI;AACX,cAAY,IAAI;AAClB;AAEA,CAAC;AACC,WAAS;AACT,OAAK;AACL,cAAY;AACZ,eAAa;AACb,cAAY,IAAI,MAAM,IAAI;AAC5B;AAEA,CAAC;AACC,WAAS;AACT,eAAa;AACb,mBAAiB;AACjB,OAAK;AACL,WAAS,IAAI;AACb,aAAW;AACX,eAAa;AACb,iBAAe,IAAI;AACnB,UAAQ;AACR,cAAY,IAAI,MAAM;AACtB,UAAQ,IAAI,MAAM,IAAI;AACtB,cAAY,IAAI;AAChB,SAAO,IAAI;AACb;AAEA,CAhBC,gBAgBgB;AACf,SAAO,IAAI;AACX,gBAAc,IAAI;AACpB;AAEA,CAAC;AACC,SAAO,IAAI;AACb;AAEA,CAAC;AACC,SAAO,IAAI;AACX,gBAAc;AACd,cAAY;AACd;AAEA,CANC,wBAMwB;AACvB,cAAY;AACZ,gBAAc,IAAI;AACpB;AAMA,CAAC;AACC,aAAW;AACb;AAEA,CAAC;AACC,iBAAe;AACf,kBAAgB;AAChB,iBAAe,IAAI,MAAM,IAAI;AAC/B;AAEA,CANC,qBAMqB;AACpB,iBAAe;AACf,kBAAgB;AAChB,iBAAe;AACjB;AAEA,CAAC;AACC,aAAW;AACX,eAAa;AACb,SAAO,IAAI;AACX,UAAQ,EAAE,EAAE,KAAK;AACnB;AAEA,CAAC;AACC,iBAAe;AACjB;AAEA,CAJC,mBAImB;AAClB,iBAAe;AACjB;AAEA,CAAC;AACC,iBAAe;AACjB;AAEA,CAAC;AACC,WAAS;AACT,aAAW;AACX,eAAa;AACb,SAAO,IAAI;AACX,iBAAe;AACjB;AAEA,CAAC;AACD,CAAC;AACC,SAAO;AACP,WAAS,KAAK;AACd,aAAW;AACX,SAAO,IAAI;AACX,cAAY,IAAI;AAChB,UAAQ,IAAI,MAAM,IAAI;AACtB,iBAAe,IAAI;AACnB,cAAY,IAAI,MAAM;AACxB;AAEA,CAZC,mBAYmB;AACpB,CAZC,sBAYsB;AACrB,WAAS;AACT,gBAAc,IAAI;AACpB;AAEA,CAlBC,mBAkBmB;AACpB,CAlBC,sBAkBsB;AACrB,SAAO,IAAI;AACb;AAEA,CAtBC;AAuBC,cAAY;AACZ,UAAQ;AACV;AAEA,CAAC;AACC,WAAS;AACT,eAAa;AACb,OAAK;AACL,UAAQ;AACR,aAAW;AACX,SAAO,IAAI;AACb;AAEA,CAAC;AACC,SAAO;AACP,UAAQ;AACR,gBAAc,IAAI;AAClB,UAAQ;AACV;AAEA,CAAC;AACC,aAAW;AACX,SAAO,IAAI;AACX,UAAQ,IAAI,EAAE,EAAE;AAClB;AAEA,CA9DC,8BA8D8B,CAN9B;AAOC,eAAa;AACf;AAMA,CAAC;AACC,aAAW;AACb;AAEA,CAAC;AACC,WAAS;AACT,eAAa;AACb,mBAAiB;AACjB,OAAK;AACL,iBAAe;AACjB;AAEA,CAAC;AACC,QAAM;AACR;AAEA,CAAC;AACC,aAAW;AACX,eAAa;AACb,SAAO,IAAI;AACX,UAAQ,EAAE,EAAE,IAAI;AAClB;AAEA,CAAC;AACC,aAAW;AACX,SAAO,IAAI;AACX,UAAQ;AACV;AAEA,CAAC;AACC,WAAS;AACT,OAAK;AACP;AAEA,CAAC;AACC,WAAS,IAAI;AACb,aAAW;AACX,eAAa;AACb,SAAO;AACP,cAAY,IAAI;AAChB,UAAQ;AACR,iBAAe,IAAI;AACnB,UAAQ;AACR,cAAY,IAAI,MAAM;AACtB,eAAa;AACf;AAEA,CAbC,0BAa0B;AACzB,cAAY,IAAI;AAClB;AAEA,CAAC;AACC,SAAO,IAAI;AACX,cAAY,IAAI;AAChB,UAAQ,IAAI,MAAM,IAAI;AACxB;AAEA,CANC,qCAMqC;AACpC,cAAY,IAAI;AAChB,gBAAc,IAAI;AACpB;AAGA,CAAC;AACC,WAAS;AACT,kBAAgB;AAChB,eAAa;AACb,mBAAiB;AACjB,WAAS,KAAK;AACd,cAAY,IAAI;AAChB,UAAQ,IAAI,OAAO,IAAI;AACvB,iBAAe,IAAI;AACnB,cAAY;AACd;AAEA,CAAC;AACC,aAAW;AACX,iBAAe;AACf,WAAS;AACX;AAEA,CAAC;AACC,aAAW;AACX,eAAa;AACb,SAAO,IAAI;AACX,UAAQ,EAAE,EAAE,IAAI;AAClB;AAEA,CAAC;AACC,aAAW;AACX,SAAO,IAAI;AACX,UAAQ,EAAE,EAAE,KAAK;AACjB,aAAW;AACb;AAEA,CAAC;AACC,WAAS;AACT,OAAK;AACP;AAGA,CAAC;AACC,WAAS;AACT,kBAAgB;AAChB,OAAK;AACP;AAGA,CAAC;AACC,cAAY,IAAI;AAChB,UAAQ,IAAI,MAAM,IAAI;AACtB,iBAAe,IAAI;AACnB,YAAU;AACZ;AAEA,CAAC;AACC,WAAS;AACX;AAEA,CAAC;AACC,WAAS;AACT,eAAa;AACb,mBAAiB;AACjB,OAAK;AACL,WAAS,KAAK;AACd,cAAY,IAAI;AAChB,iBAAe,IAAI,MAAM,IAAI;AAC/B;AAEA,CAAC;AACC,WAAS;AACT,eAAa;AACb,OAAK;AACL,QAAM;AACN,aAAW;AACb;AAGA,CAAC;AACC,YAAU;AACV,WAAS;AACT,SAAO;AACP,UAAQ;AACR,eAAa;AACf;AAEA,CARC,yBAQyB;AACxB,WAAS;AACT,SAAO;AACP,UAAQ;AACV;AAEA,CAAC;AACC,YAAU;AACV,UAAQ;AACR,OAAK;AACL,QAAM;AACN,SAAO;AACP,UAAQ;AACR,oBAAkB,IAAI;AACtB,cAAY;AACZ,iBAAe;AACjB;AAEA,CAZC,+BAY+B;AAC9B,YAAU;AACV,WAAS;AACT,UAAQ;AACR,SAAO;AACP,QAAM;AACN,UAAQ;AACR,oBAAkB;AAClB,cAAY;AACZ,iBAAe;AACjB;AAEA,CAtCC,yBAsCyB,KAAK,SAAS,EAAE,CAxBzC;AAyBC,oBAAkB,IAAI;AACxB;AAEA,CA1CC,yBA2CC,KAAK,SACL,EAAE,CA9BH,+BA8BmC;AAClC,aAAW,WAAW;AACxB;AAEA,CAAC;AACC,QAAM;AACN,aAAW;AACX,WAAS,IAAI;AACb,aAAW;AACX,eAAa;AACb,SAAO,IAAI;AACX,cAAY,IAAI;AAChB,UAAQ,IAAI,MAAM;AAClB,iBAAe,IAAI;AACnB,cAAY,IAAI,MAAM;AACxB;AAEA,CAbC,sBAasB;AACrB,WAAS;AACT,gBAAc,IAAI;AACpB;AAEA,CAAC;AACC,WAAS,IAAI;AACb,aAAW;AACX,eAAa;AACb,kBAAgB;AAChB,kBAAgB;AAChB,iBAAe;AACf,eAAa;AACf;AAEA,CAAC;AACC,SAAO;AACP,cAAY;AACd;AAEA,CAAC;AACC,SAAO;AACP,cAAY;AACd;AAEA,CAAC;AACC,WAAS,IAAI;AACb,aAAW;AACX,eAAa;AACb,SAAO,IAAI;AACX,cAAY;AACZ,UAAQ,IAAI,MAAM,IAAI;AACtB,iBAAe,IAAI;AACnB,UAAQ;AACR,cAAY,IAAI,MAAM;AACxB;AAEA,CAZC,wBAYwB;AACvB,SAAO,IAAI;AACX,gBAAc,IAAI;AAClB,cAAY;AACd;AAEA,CAAC;AACC,WAAS;AACX;AAEA,CAAC;AACC,iBAAe;AACjB;AAEA,CAJC,qBAIqB;AACpB,iBAAe;AACjB;AAEA,CAAC;AACC,WAAS;AACT,yBAAuB,IAAI;AAC3B,OAAK;AACP;AAEA,CAAC;AACC,WAAS;AACT,kBAAgB;AAChB,OAAK;AACP;AAEA,CAAC;AACC,aAAW;AACX,eAAa;AACb,SAAO,IAAI;AACb;AAEA,CAAC;AACD,CAAC;AACC,WAAS,KAAK;AACd,aAAW;AACX,SAAO,IAAI;AACX,cAAY,IAAI;AAChB,UAAQ,IAAI,MAAM,IAAI;AACtB,iBAAe,IAAI;AACnB,cAAY,IAAI,MAAM;AACxB;AAEA,CAXC,uBAWuB;AACxB,CAXC,0BAW0B;AACzB,WAAS;AACT,gBAAc,IAAI;AACpB;AAEA,CAjBC,uBAiBuB;AACxB,CAjBC,0BAiB0B;AACzB,SAAO,IAAI;AACb;AAEA,CArBC;AAsBC,cAAY;AACZ,UAAQ;AACR,eAAa;AACf;AAEA,CAAC;AACC,aAAW;AACX,SAAO,IAAI;AACb;AAEA,CALC,uBAKuB;AACtB,UAAQ,EAAE,EAAE,IAAI;AAClB;AAEA,CAAC;AACC,UAAQ;AACR,gBAAc;AACd,cAAY;AACd;AAEA,CANC,+BAM+B;AAC9B,iBAAe;AACjB;AAEA,CAVC,+BAU+B;AAC9B,aAAW;AACX,SAAO,IAAI;AACX,cAAY,IAAI;AAChB,WAAS,IAAI;AACb,iBAAe;AACjB;AAGA,CAAC;AACC,cAAY;AACZ,WAAS,KAAK;AACd,cAAY,IAAI;AAChB,iBAAe,IAAI;AACrB;AAEA,CAPC,wBAOwB;AACvB,aAAW;AACX,eAAa;AACb,SAAO,IAAI;AACX,UAAQ,EAAE,EAAE,KAAK;AACnB;AAEA,CAdC,wBAcwB;AACvB,UAAQ;AACR,gBAAc;AACd,aAAW;AACX,SAAO,IAAI;AACX,eAAa;AACf;AAEA,CAtBC,wBAsBwB;AACvB,iBAAe;AACjB;AAEA,CA1BC,wBA0BwB,EAAE;AACzB,iBAAe;AACjB;AAEA,CA9BC,wBA8BwB;AACvB,SAAO,IAAI;AACb;AAMA,CAAC;AACC,WAAS;AACT,eAAa;AACb,mBAAiB;AACjB,OAAK;AACL,WAAS,KAAK;AACd,cAAY,IAAI;AAChB,UAAQ,IAAI,MAAM,IAAI;AACtB,iBAAe,IAAI;AACnB,cAAY,aAAa,MAAM;AACjC;AAEA,CAZC,qBAYqB;AACpB,gBAAc,IAAI;AACpB;AAEA,CAAC;AACC,WAAS;AACX;AAEA,CAAC;AACC,WAAS;AACT,eAAa;AACb,OAAK;AACL,QAAM;AACN,aAAW;AACb;AAEA,CAAC;AACC,WAAS;AACT,kBAAgB;AAChB,OAAK;AACL,aAAW;AACb;AAEA,CAAC;AACC,aAAW;AACX,eAAa;AACb,SAAO,IAAI;AACX,eAAa;AACb,YAAU;AACV,iBAAe;AACjB;AAEA,CAAC;AACC,aAAW;AACX,SAAO,IAAI;AACb;AAEA,CAAC;AACC,WAAS;AACT,OAAK;AACL,eAAa;AACf;AAEA,CAAC;AACC,WAAS,IAAI;AACb,aAAW;AACX,eAAa;AACb,iBAAe,IAAI;AACnB,UAAQ;AACR,cAAY,IAAI,MAAM;AACtB,UAAQ,IAAI,MAAM,IAAI;AACtB,cAAY;AACd;AAEA,CAAC;AACC,SAAO,IAAI;AACb;AAEA,CAJC,0BAI0B;AACzB,SAAO,IAAI;AACX,gBAAc,IAAI;AAClB,cAAY,IAAI;AAClB;AAEA,CAAC;AACC,SAAO,IAAI;AACb;AAEA,CAJC,4BAI4B;AAC3B,SAAO,IAAI;AACX,gBAAc,IAAI;AAClB,cAAY;AACd;AAMA,CAAC;AACC,YAAU;AACV,SAAO;AACP,cAAY,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;AAC1B,WAAS;AACT,eAAa;AACb,mBAAiB;AACjB,WAAS;AACT,WAAS;AACX;AAEA,CAAC;AACC,cAAY,IAAI;AAChB,UAAQ,IAAI,MAAM,IAAI;AACtB,iBAAe,IAAI;AACnB,SAAO;AACP,aAAW;AACX,cAAY,KAAK,MAAM,EAAE;AACzB,WAAS;AACT,kBAAgB;AAChB,cACE,EAAE,KAAK,KAAK,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAC/B,EAAE,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;AAC7B;AAEA,CAAC;AACC,WAAS,KAAK,KAAK;AACnB,iBAAe,IAAI,MAAM,IAAI;AAC7B,eAAa;AACf;AAEA,CAAC;AACC,aAAW;AACX,eAAa;AACb,SAAO,IAAI;AACX,UAAQ;AACV;AAEA,CAAC;AACC,WAAS,KAAK;AACd,cAAY;AACZ,WAAS;AACT,kBAAgB;AAChB,OAAK;AACL,QAAM;AACR;AAEA,CAAC;AACC,WAAS,KAAK;AACd,cAAY,IAAI,MAAM,IAAI;AAC1B,WAAS;AACT,mBAAiB;AACjB,OAAK;AACL,eAAa;AACf;AAGA,CAAC;AACC,WAAS,KAAK;AACd,aAAW;AACX,SAAO,IAAI;AACX,cAAY,IAAI;AAChB,UAAQ,IAAI,MAAM,IAAI;AACtB,iBAAe,IAAI;AACnB,cAAY,IAAI,MAAM;AACtB,cAAY;AACZ,oBAAkB;AAClB,qBAAmB;AACnB,uBAAqB,MAAM,KAAK;AAChC,iBAAe;AACf,UAAQ;AACV;AAEA,CAhBC,uBAgBuB;AACtB,WAAS;AACT,gBAAc,IAAI;AAClB,cAAY,EAAE,EAAE,EAAE,IAAI,KAAK,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE;AAC3C;AAGA,CAAC;AACC,WAAS;AACT,kBAAgB;AAChB,OAAK;AACL,iBAAe;AACjB;AAEA,CAAC;AACC,WAAS;AACT,eAAa;AACb,mBAAiB;AACjB,WAAS,IAAI;AACb,cAAY,IAAI;AAChB,UAAQ,IAAI,MAAM,IAAI;AACtB,iBAAe,IAAI;AACnB,aAAW;AACX,SAAO,IAAI;AACb;AAEA,CAAC;AACC,cAAY;AACZ,UAAQ;AACR,SAAO,IAAI;AACX,UAAQ;AACR,aAAW;AACX,eAAa;AACb,WAAS,EAAE;AACX,cAAY,MAAM,MAAM;AAC1B;AAEA,CAXC,iCAWiC;AAChC,SAAO,IAAI;AACb;AAEA,CAAC;AACC,WAAS;AACT,OAAK;AACP;AAEA,CALC,+BAK+B,CA/S/B;AAgTC,QAAM;AACR;AAEA,CAAC;AACC,WAAS,KAAK;AACd,aAAW;AACX,eAAa;AACb,SAAO,IAAI;AACX,cAAY,IAAI;AAChB,UAAQ,IAAI,MAAM,IAAI;AACtB,iBAAe,IAAI;AACnB,UAAQ;AACR,eAAa;AACb,cAAY,IAAI,MAAM;AACtB,eAAa;AACf;AAEA,CAdC,kCAckC;AACjC,cAAY,IAAI;AAChB,gBAAc,IAAI;AACpB;AAGA,CAAC;AACC,WAAS;AACT,eAAa;AACb,mBAAiB;AACjB,WAAS,KAAK,EAAE;AAChB,cAAY,IAAI,MAAM,IAAI;AAC5B;AAEA,CAAC;AACC,aAAW;AACX,eAAa;AACb,SAAO,IAAI;AACb;AAGA,CAAC;AACC,WAAS,IAAI;AACb,aAAW;AACX,eAAa;AACb,SAAO,IAAI;AACX,cAAY,IAAI;AAChB,UAAQ,IAAI,MAAM,IAAI;AACtB,iBAAe,IAAI;AACnB,UAAQ;AACR,cAAY,IAAI,MAAM;AACxB;AAEA,CAZC,2BAY2B;AAC1B,cAAY,IAAI;AAChB,gBAAc,IAAI;AACpB;AAEA,CAAC;AACC,WAAS,IAAI;AACb,aAAW;AACX,eAAa;AACb,SAAO;AACP,cAAY,IAAI;AAChB,UAAQ;AACR,iBAAe,IAAI;AACnB,UAAQ;AACR,cAAY,WAAW,MAAM;AAC/B;AAEA,CAZC,yBAYyB;AACxB,cAAY,IAAI;AAClB;","names":[]}
|
|
@@ -0,0 +1,547 @@
|
|
|
1
|
+
import { ComponentPath } from '@nextlyhq/admin/lib/component-registry';
|
|
2
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
3
|
+
import { i as FormField, p as FormFieldType } from '../index-C0kBvYjm.js';
|
|
4
|
+
export { J as SubmissionDetail, t as SubmissionDetailProps, K as SubmissionList, u as SubmissionListProps } from '../index-C0kBvYjm.js';
|
|
5
|
+
import { ReactNode } from 'react';
|
|
6
|
+
import 'nextly';
|
|
7
|
+
|
|
8
|
+
interface FormBuilderViewProps {
|
|
9
|
+
id?: string;
|
|
10
|
+
entryId?: string;
|
|
11
|
+
collection?: string;
|
|
12
|
+
collectionSlug?: string;
|
|
13
|
+
isCreating?: boolean;
|
|
14
|
+
initialData?: {
|
|
15
|
+
id?: string;
|
|
16
|
+
name?: string;
|
|
17
|
+
slug?: string;
|
|
18
|
+
description?: string;
|
|
19
|
+
status?: "draft" | "published" | "closed";
|
|
20
|
+
fields?: unknown[];
|
|
21
|
+
settings?: Record<string, unknown>;
|
|
22
|
+
notifications?: unknown[];
|
|
23
|
+
};
|
|
24
|
+
onSave?: (data: unknown) => void;
|
|
25
|
+
onSuccess?: (entry?: Record<string, unknown>) => void;
|
|
26
|
+
onCancel?: () => void;
|
|
27
|
+
}
|
|
28
|
+
declare function FormBuilderView({ id, entryId, collection, collectionSlug, isCreating, initialData, onSave, onSuccess, onCancel, }: FormBuilderViewProps): react_jsx_runtime.JSX.Element;
|
|
29
|
+
|
|
30
|
+
interface SubmissionsFilterProps {
|
|
31
|
+
/** Collection slug (should be "form-submissions") */
|
|
32
|
+
collectionSlug: string;
|
|
33
|
+
/** Collection configuration */
|
|
34
|
+
collection: Record<string, unknown>;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* SubmissionsFilter - Filter submissions by form
|
|
38
|
+
*
|
|
39
|
+
* Displays a dropdown of all forms. When a form is selected,
|
|
40
|
+
* updates the URL query params to filter the submissions list.
|
|
41
|
+
*/
|
|
42
|
+
declare function SubmissionsFilter({ collectionSlug, }: SubmissionsFilterProps): React.ReactElement | null;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* FieldLibrary — Right-sidebar field type palette
|
|
46
|
+
*
|
|
47
|
+
* Mirrors the Collection Builder's FieldPalette:
|
|
48
|
+
* - Search bar at top
|
|
49
|
+
* - Accordion categories (Basic / Advanced)
|
|
50
|
+
* - Blue icon boxes with draggable rows
|
|
51
|
+
* - Click or drag to add a field
|
|
52
|
+
*/
|
|
53
|
+
declare function FieldLibrary(): react_jsx_runtime.JSX.Element;
|
|
54
|
+
|
|
55
|
+
interface FormCanvasProps {
|
|
56
|
+
fields: FormField[];
|
|
57
|
+
selectedFieldId: string | null;
|
|
58
|
+
onFieldSelect: (fieldName: string | null) => void;
|
|
59
|
+
onFieldDelete: (fieldName: string) => void;
|
|
60
|
+
}
|
|
61
|
+
declare function FormCanvas({ fields, selectedFieldId, onFieldSelect, onFieldDelete, }: FormCanvasProps): react_jsx_runtime.JSX.Element;
|
|
62
|
+
|
|
63
|
+
interface FieldEditorProps {
|
|
64
|
+
/** The field being edited */
|
|
65
|
+
field: FormField;
|
|
66
|
+
/** All fields in the form (for conditional logic references) */
|
|
67
|
+
allFields: FormField[];
|
|
68
|
+
/** Callback when field is updated */
|
|
69
|
+
onUpdate: (updates: Partial<FormField>) => void;
|
|
70
|
+
/** Callback when field is deleted */
|
|
71
|
+
onDelete: () => void;
|
|
72
|
+
/** Callback when field is duplicated */
|
|
73
|
+
onDuplicate?: () => void;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* FieldEditor - Field properties configuration panel
|
|
77
|
+
*
|
|
78
|
+
* Provides a tabbed interface for editing field properties:
|
|
79
|
+
* - General: name, label, placeholder, help text, required, width, type-specific options
|
|
80
|
+
* - Validation: error messages, min/max length, patterns, etc.
|
|
81
|
+
* - Conditional: show/hide logic based on other field values
|
|
82
|
+
*
|
|
83
|
+
* @example
|
|
84
|
+
* ```tsx
|
|
85
|
+
* <FieldEditor
|
|
86
|
+
* field={selectedField}
|
|
87
|
+
* allFields={allFields}
|
|
88
|
+
* onUpdate={handleUpdate}
|
|
89
|
+
* onDelete={handleDelete}
|
|
90
|
+
* onDuplicate={handleDuplicate}
|
|
91
|
+
* />
|
|
92
|
+
* ```
|
|
93
|
+
*/
|
|
94
|
+
declare function FieldEditor({ field, allFields, onUpdate, onDelete, onDuplicate, }: FieldEditorProps): react_jsx_runtime.JSX.Element;
|
|
95
|
+
|
|
96
|
+
interface FormPreviewProps {
|
|
97
|
+
/** Array of form fields to preview */
|
|
98
|
+
fields: FormField[];
|
|
99
|
+
/** Form metadata */
|
|
100
|
+
formData?: {
|
|
101
|
+
name?: string;
|
|
102
|
+
slug?: string;
|
|
103
|
+
description?: string;
|
|
104
|
+
status?: string;
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* FormPreview - Visual form preview
|
|
109
|
+
*
|
|
110
|
+
* This is a stub component that shows a preview of the form.
|
|
111
|
+
* The full implementation will include:
|
|
112
|
+
* - Rendered form fields with proper styling
|
|
113
|
+
* - Responsive preview modes (desktop, tablet, mobile)
|
|
114
|
+
* - Theme preview options
|
|
115
|
+
* - Conditional logic simulation
|
|
116
|
+
*
|
|
117
|
+
* @example
|
|
118
|
+
* ```tsx
|
|
119
|
+
* <FormPreview fields={fields} formData={formData} />
|
|
120
|
+
* ```
|
|
121
|
+
*/
|
|
122
|
+
declare function FormPreview({ fields, formData }: FormPreviewProps): react_jsx_runtime.JSX.Element;
|
|
123
|
+
|
|
124
|
+
interface FormFieldListProps {
|
|
125
|
+
/**
|
|
126
|
+
* Array of form fields to display.
|
|
127
|
+
*/
|
|
128
|
+
fields: FormField[];
|
|
129
|
+
/**
|
|
130
|
+
* Callback when fields are reordered via drag-and-drop.
|
|
131
|
+
* Receives the new array with fields in updated order.
|
|
132
|
+
*/
|
|
133
|
+
onFieldsChange: (fields: FormField[]) => void;
|
|
134
|
+
/**
|
|
135
|
+
* Callback when a field is selected for editing.
|
|
136
|
+
* Receives the field name (unique identifier).
|
|
137
|
+
*/
|
|
138
|
+
onEditField: (fieldName: string) => void;
|
|
139
|
+
/**
|
|
140
|
+
* Callback when a field should be deleted.
|
|
141
|
+
* Receives the field name (unique identifier).
|
|
142
|
+
*/
|
|
143
|
+
onDeleteField: (fieldName: string) => void;
|
|
144
|
+
/**
|
|
145
|
+
* Currently selected field name for highlighting.
|
|
146
|
+
*/
|
|
147
|
+
selectedFieldName?: string | null;
|
|
148
|
+
/**
|
|
149
|
+
* Whether the list is disabled (no interactions allowed).
|
|
150
|
+
* @default false
|
|
151
|
+
*/
|
|
152
|
+
disabled?: boolean;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* FormFieldList provides a drag-and-drop sortable container for form fields.
|
|
156
|
+
*
|
|
157
|
+
* This component wraps fields with DndContext and SortableContext from @dnd-kit,
|
|
158
|
+
* enabling drag-and-drop reordering with full keyboard accessibility.
|
|
159
|
+
*
|
|
160
|
+
* The component follows the pattern established by ArrayInput.tsx in the
|
|
161
|
+
* Nextly admin package:
|
|
162
|
+
* - PointerSensor with 8px activation distance (prevents accidental drags)
|
|
163
|
+
* - KeyboardSensor with sortableKeyboardCoordinates (arrow key navigation)
|
|
164
|
+
* - closestCenter collision detection
|
|
165
|
+
* - verticalListSortingStrategy for vertical lists
|
|
166
|
+
*
|
|
167
|
+
* @example
|
|
168
|
+
* ```tsx
|
|
169
|
+
* <FormFieldList
|
|
170
|
+
* fields={formFields}
|
|
171
|
+
* onFieldsChange={setFormFields}
|
|
172
|
+
* onEditField={(name) => setSelectedField(name)}
|
|
173
|
+
* onDeleteField={(name) => handleDeleteField(name)}
|
|
174
|
+
* selectedFieldName={selectedField}
|
|
175
|
+
* />
|
|
176
|
+
* ```
|
|
177
|
+
*/
|
|
178
|
+
declare function FormFieldList({ fields, onFieldsChange, onEditField, onDeleteField, selectedFieldName, disabled, }: FormFieldListProps): react_jsx_runtime.JSX.Element;
|
|
179
|
+
|
|
180
|
+
interface SortableFieldRowProps {
|
|
181
|
+
/**
|
|
182
|
+
* The form field to display.
|
|
183
|
+
*/
|
|
184
|
+
field: FormField;
|
|
185
|
+
/**
|
|
186
|
+
* Whether this row is currently selected for editing.
|
|
187
|
+
*/
|
|
188
|
+
isSelected: boolean;
|
|
189
|
+
/**
|
|
190
|
+
* Callback when the row is clicked/selected.
|
|
191
|
+
*/
|
|
192
|
+
onSelect: () => void;
|
|
193
|
+
/**
|
|
194
|
+
* Callback when the delete button is clicked.
|
|
195
|
+
*/
|
|
196
|
+
onDelete: () => void;
|
|
197
|
+
/**
|
|
198
|
+
* Whether the row is disabled (no interactions allowed).
|
|
199
|
+
* @default false
|
|
200
|
+
*/
|
|
201
|
+
disabled?: boolean;
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* SortableFieldRow renders a single draggable field row in the form builder.
|
|
205
|
+
*
|
|
206
|
+
* Uses @dnd-kit's useSortable hook to enable drag-and-drop reordering.
|
|
207
|
+
* The component displays:
|
|
208
|
+
* - A drag handle (GripVertical icon) for reordering
|
|
209
|
+
* - The field type icon
|
|
210
|
+
* - The field label (or name as fallback) with required indicator
|
|
211
|
+
* - The field type badge
|
|
212
|
+
* - A delete button
|
|
213
|
+
*
|
|
214
|
+
* Visual feedback is provided during drag operations:
|
|
215
|
+
* - Reduced opacity (50%)
|
|
216
|
+
* - Primary color ring (2px)
|
|
217
|
+
* - Elevated shadow
|
|
218
|
+
* - Higher z-index
|
|
219
|
+
*
|
|
220
|
+
* @example
|
|
221
|
+
* ```tsx
|
|
222
|
+
* <SortableFieldRow
|
|
223
|
+
* field={field}
|
|
224
|
+
* isSelected={selectedFieldName === field.name}
|
|
225
|
+
* onSelect={() => setSelectedFieldName(field.name)}
|
|
226
|
+
* onDelete={() => handleDeleteField(field.name)}
|
|
227
|
+
* />
|
|
228
|
+
* ```
|
|
229
|
+
*/
|
|
230
|
+
declare function SortableFieldRow({ field, isSelected, onSelect, onDelete, disabled, }: SortableFieldRowProps): react_jsx_runtime.JSX.Element;
|
|
231
|
+
|
|
232
|
+
interface AddFieldButtonProps {
|
|
233
|
+
/**
|
|
234
|
+
* Callback when a new field is created.
|
|
235
|
+
* Receives the newly created FormField instance.
|
|
236
|
+
*/
|
|
237
|
+
onAddField: (field: FormField) => void;
|
|
238
|
+
/**
|
|
239
|
+
* Whether the button is disabled.
|
|
240
|
+
* @default false
|
|
241
|
+
*/
|
|
242
|
+
disabled?: boolean;
|
|
243
|
+
/**
|
|
244
|
+
* Additional CSS class names for the button.
|
|
245
|
+
*/
|
|
246
|
+
className?: string;
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* AddFieldButton renders a button that opens a modal for selecting field types.
|
|
250
|
+
*
|
|
251
|
+
* When a field type is selected, a new field instance is created with default
|
|
252
|
+
* configuration and passed to the onAddField callback. The modal automatically
|
|
253
|
+
* closes after selection.
|
|
254
|
+
*
|
|
255
|
+
* @example
|
|
256
|
+
* ```tsx
|
|
257
|
+
* <AddFieldButton
|
|
258
|
+
* onAddField={(field) => {
|
|
259
|
+
* setFields([...fields, field]);
|
|
260
|
+
* }}
|
|
261
|
+
* />
|
|
262
|
+
* ```
|
|
263
|
+
*/
|
|
264
|
+
declare function AddFieldButton({ onAddField, disabled, className, }: AddFieldButtonProps): react_jsx_runtime.JSX.Element;
|
|
265
|
+
|
|
266
|
+
interface FieldEditorPanelProps {
|
|
267
|
+
/**
|
|
268
|
+
* The field being edited.
|
|
269
|
+
*/
|
|
270
|
+
field: FormField;
|
|
271
|
+
/**
|
|
272
|
+
* All fields in the form (for references, e.g., conditional logic).
|
|
273
|
+
*/
|
|
274
|
+
allFields: FormField[];
|
|
275
|
+
/**
|
|
276
|
+
* Callback when field properties are updated.
|
|
277
|
+
* Receives partial updates to merge with current field.
|
|
278
|
+
*/
|
|
279
|
+
onUpdate: (updates: Partial<FormField>) => void;
|
|
280
|
+
/**
|
|
281
|
+
* Callback when the panel should be closed.
|
|
282
|
+
*/
|
|
283
|
+
onClose: () => void;
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* FieldEditorPanel - Right-side panel for editing field properties
|
|
287
|
+
*
|
|
288
|
+
* This component dynamically loads the appropriate field editor based on
|
|
289
|
+
* the field type. Each field type has its own editor component that handles
|
|
290
|
+
* the specific configuration options for that type.
|
|
291
|
+
*
|
|
292
|
+
* The panel displays:
|
|
293
|
+
* - Header with field type icon, type label, and field label
|
|
294
|
+
* - Close button to dismiss the panel
|
|
295
|
+
* - Lazy-loaded editor content with loading skeleton
|
|
296
|
+
*
|
|
297
|
+
* @example
|
|
298
|
+
* ```tsx
|
|
299
|
+
* <FieldEditorPanel
|
|
300
|
+
* field={selectedField}
|
|
301
|
+
* allFields={allFields}
|
|
302
|
+
* onUpdate={(updates) => updateField(selectedField.name, updates)}
|
|
303
|
+
* onClose={() => setSelectedField(null)}
|
|
304
|
+
* />
|
|
305
|
+
* ```
|
|
306
|
+
*/
|
|
307
|
+
declare function FieldEditorPanel({ field, allFields, onUpdate, onClose, }: FieldEditorPanelProps): react_jsx_runtime.JSX.Element;
|
|
308
|
+
|
|
309
|
+
/** Form settings configuration */
|
|
310
|
+
interface FormSettings {
|
|
311
|
+
/** Submit button text */
|
|
312
|
+
submitButtonText: string;
|
|
313
|
+
/** Show reset button */
|
|
314
|
+
showResetButton: boolean;
|
|
315
|
+
/** Reset button text */
|
|
316
|
+
resetButtonText: string;
|
|
317
|
+
/** Success message after submission */
|
|
318
|
+
confirmationMessage: string;
|
|
319
|
+
/** Redirect URL after submission (optional) */
|
|
320
|
+
redirectUrl?: string;
|
|
321
|
+
/** Enable honeypot spam protection */
|
|
322
|
+
honeypotEnabled: boolean;
|
|
323
|
+
/** Enable CAPTCHA */
|
|
324
|
+
captchaEnabled: boolean;
|
|
325
|
+
/** Store submissions in database */
|
|
326
|
+
storeSubmissions: boolean;
|
|
327
|
+
/** Limit submissions per user/IP */
|
|
328
|
+
submissionLimit?: number;
|
|
329
|
+
}
|
|
330
|
+
/** Email notification configuration */
|
|
331
|
+
interface FormNotification {
|
|
332
|
+
/** Unique ID for this notification */
|
|
333
|
+
id: string;
|
|
334
|
+
/** Notification name */
|
|
335
|
+
name: string;
|
|
336
|
+
/** Whether this notification is enabled */
|
|
337
|
+
enabled: boolean;
|
|
338
|
+
/** ID of the email provider to use; undefined = system default */
|
|
339
|
+
providerId?: string;
|
|
340
|
+
/** Sender email override; undefined = use provider's configured address */
|
|
341
|
+
senderEmail?: string;
|
|
342
|
+
/** How the recipient address is determined */
|
|
343
|
+
recipientType: "static" | "field";
|
|
344
|
+
/** Recipient address: static email or a {{fieldName}} reference */
|
|
345
|
+
to: string;
|
|
346
|
+
/** CC email addresses */
|
|
347
|
+
cc: string[];
|
|
348
|
+
/** BCC email addresses */
|
|
349
|
+
bcc: string[];
|
|
350
|
+
/** Slug of the email template to use */
|
|
351
|
+
templateSlug?: string;
|
|
352
|
+
}
|
|
353
|
+
interface FormBuilderState {
|
|
354
|
+
/** Form fields array */
|
|
355
|
+
fields: FormField[];
|
|
356
|
+
/** Currently selected field ID (name) */
|
|
357
|
+
selectedFieldId: string | null;
|
|
358
|
+
/** Active tab: builder, preview, settings, or notifications */
|
|
359
|
+
activeTab: "builder" | "preview" | "settings" | "notifications";
|
|
360
|
+
/** Whether form has unsaved changes */
|
|
361
|
+
isDirty: boolean;
|
|
362
|
+
/** Form metadata */
|
|
363
|
+
formData: {
|
|
364
|
+
id?: string;
|
|
365
|
+
name: string;
|
|
366
|
+
slug: string;
|
|
367
|
+
description?: string;
|
|
368
|
+
status: "draft" | "published" | "closed";
|
|
369
|
+
};
|
|
370
|
+
/** Form settings */
|
|
371
|
+
settings: FormSettings;
|
|
372
|
+
/** Email notifications */
|
|
373
|
+
notifications: FormNotification[];
|
|
374
|
+
}
|
|
375
|
+
interface FormBuilderActions {
|
|
376
|
+
/** Set all fields */
|
|
377
|
+
setFields: (fields: FormField[]) => void;
|
|
378
|
+
/** Add a new field */
|
|
379
|
+
addField: (field: FormField, index?: number) => void;
|
|
380
|
+
/** Update a field by name */
|
|
381
|
+
updateField: (fieldName: string, updates: Partial<FormField>) => void;
|
|
382
|
+
/** Delete a field by name */
|
|
383
|
+
deleteField: (fieldName: string) => void;
|
|
384
|
+
/** Move a field from one index to another */
|
|
385
|
+
moveField: (fromIndex: number, toIndex: number) => void;
|
|
386
|
+
/** Duplicate a field */
|
|
387
|
+
duplicateField: (fieldName: string) => void;
|
|
388
|
+
/** Select a field */
|
|
389
|
+
selectField: (fieldName: string | null) => void;
|
|
390
|
+
/** Set active tab */
|
|
391
|
+
setActiveTab: (tab: "builder" | "preview" | "settings" | "notifications") => void;
|
|
392
|
+
/** Update form metadata */
|
|
393
|
+
updateFormData: (updates: Partial<FormBuilderState["formData"]>) => void;
|
|
394
|
+
/** Update form settings */
|
|
395
|
+
updateSettings: (updates: Partial<FormSettings>) => void;
|
|
396
|
+
/** Add a notification */
|
|
397
|
+
addNotification: (notification: FormNotification) => void;
|
|
398
|
+
/** Update a notification */
|
|
399
|
+
updateNotification: (id: string, updates: Partial<FormNotification>) => void;
|
|
400
|
+
/** Delete a notification */
|
|
401
|
+
deleteNotification: (id: string) => void;
|
|
402
|
+
/** Mark form as saved (clears dirty flag) */
|
|
403
|
+
markAsSaved: () => void;
|
|
404
|
+
}
|
|
405
|
+
interface FormBuilderContextValue extends FormBuilderState, FormBuilderActions {
|
|
406
|
+
}
|
|
407
|
+
interface FormBuilderProviderProps {
|
|
408
|
+
/** Initial form data (for editing existing forms) */
|
|
409
|
+
initialData?: {
|
|
410
|
+
id?: string;
|
|
411
|
+
name?: string;
|
|
412
|
+
slug?: string;
|
|
413
|
+
description?: string;
|
|
414
|
+
status?: "draft" | "published" | "closed";
|
|
415
|
+
fields?: FormField[];
|
|
416
|
+
settings?: Partial<FormSettings>;
|
|
417
|
+
notifications?: FormNotification[];
|
|
418
|
+
};
|
|
419
|
+
/** Child components */
|
|
420
|
+
children: ReactNode;
|
|
421
|
+
}
|
|
422
|
+
/** Default form settings */
|
|
423
|
+
declare const DEFAULT_SETTINGS: FormSettings;
|
|
424
|
+
/** Create a new email integration with default values */
|
|
425
|
+
declare function createNotification(): FormNotification;
|
|
426
|
+
/**
|
|
427
|
+
* Generate a unique field name based on type and timestamp.
|
|
428
|
+
*/
|
|
429
|
+
declare function generateFieldName(type: FormFieldType): string;
|
|
430
|
+
/**
|
|
431
|
+
* Generate a human-readable label from field type.
|
|
432
|
+
*/
|
|
433
|
+
declare function generateFieldLabel(type: FormFieldType): string;
|
|
434
|
+
/**
|
|
435
|
+
* Create a new field from a field type with default values.
|
|
436
|
+
*/
|
|
437
|
+
declare function createFieldFromType(type: FormFieldType): FormField;
|
|
438
|
+
/**
|
|
439
|
+
* FormBuilderProvider - Provides form builder state to child components
|
|
440
|
+
*
|
|
441
|
+
* Wraps the form builder UI to provide centralized state management
|
|
442
|
+
* for fields, selection, and form metadata.
|
|
443
|
+
*
|
|
444
|
+
* @example
|
|
445
|
+
* ```tsx
|
|
446
|
+
* <FormBuilderProvider initialData={existingForm}>
|
|
447
|
+
* <FormBuilderView />
|
|
448
|
+
* </FormBuilderProvider>
|
|
449
|
+
* ```
|
|
450
|
+
*/
|
|
451
|
+
declare function FormBuilderProvider({ initialData, children, }: FormBuilderProviderProps): react_jsx_runtime.JSX.Element;
|
|
452
|
+
/**
|
|
453
|
+
* useFormBuilder - Access form builder context
|
|
454
|
+
*
|
|
455
|
+
* Hook to access form builder state and actions from within the builder UI.
|
|
456
|
+
* Must be used within a FormBuilderProvider.
|
|
457
|
+
*
|
|
458
|
+
* @returns Form builder context value
|
|
459
|
+
* @throws Error if used outside of FormBuilderProvider
|
|
460
|
+
*
|
|
461
|
+
* @example
|
|
462
|
+
* ```tsx
|
|
463
|
+
* function FieldList() {
|
|
464
|
+
* const { fields, selectField, deleteField } = useFormBuilder();
|
|
465
|
+
*
|
|
466
|
+
* return (
|
|
467
|
+
* <ul>
|
|
468
|
+
* {fields.map(field => (
|
|
469
|
+
* <li key={field.name} onClick={() => selectField(field.name)}>
|
|
470
|
+
* {field.label}
|
|
471
|
+
* <button onClick={() => deleteField(field.name)}>Delete</button>
|
|
472
|
+
* </li>
|
|
473
|
+
* ))}
|
|
474
|
+
* </ul>
|
|
475
|
+
* );
|
|
476
|
+
* }
|
|
477
|
+
* ```
|
|
478
|
+
*/
|
|
479
|
+
declare function useFormBuilder(): FormBuilderContextValue;
|
|
480
|
+
/**
|
|
481
|
+
* useOptionalFormBuilder - Access form builder context safely
|
|
482
|
+
*
|
|
483
|
+
* Like useFormBuilder but returns null if not within a provider.
|
|
484
|
+
* Useful for components that may be rendered outside of the form builder.
|
|
485
|
+
*
|
|
486
|
+
* @returns Form builder context value or null
|
|
487
|
+
*/
|
|
488
|
+
declare function useOptionalFormBuilder(): FormBuilderContextValue | null;
|
|
489
|
+
|
|
490
|
+
/**
|
|
491
|
+
* FormSettingsTab - Form settings configuration panel
|
|
492
|
+
*
|
|
493
|
+
* Refined for Antigravity standard:
|
|
494
|
+
* - Two-column layout for better space utilization.
|
|
495
|
+
* - Title Case headings with improved hierarchy.
|
|
496
|
+
* - Robust state management for action tabs.
|
|
497
|
+
*/
|
|
498
|
+
declare function FormSettingsTab(): react_jsx_runtime.JSX.Element;
|
|
499
|
+
|
|
500
|
+
/**
|
|
501
|
+
* FormNotificationsTab - Email integrations configuration
|
|
502
|
+
*
|
|
503
|
+
* Allows users to configure email integrations that trigger when a form is
|
|
504
|
+
* submitted. Each integration references an existing email provider and
|
|
505
|
+
* template rather than duplicating provider credentials.
|
|
506
|
+
*/
|
|
507
|
+
declare function FormNotificationsTab(): react_jsx_runtime.JSX.Element;
|
|
508
|
+
|
|
509
|
+
/**
|
|
510
|
+
* Form Builder Admin Components
|
|
511
|
+
*
|
|
512
|
+
* Entry point for admin UI components used by the Nextly admin panel.
|
|
513
|
+
* These components are referenced via component paths in collection configs.
|
|
514
|
+
*
|
|
515
|
+
* Component paths use the format: "@nextlyhq/plugin-form-builder/admin#ExportName"
|
|
516
|
+
*
|
|
517
|
+
* ## Auto-Registration
|
|
518
|
+
*
|
|
519
|
+
* This module automatically registers its components with the admin panel
|
|
520
|
+
* when imported. No manual registration is required - just add the plugin
|
|
521
|
+
* to your Nextly config and the admin will detect and load the components.
|
|
522
|
+
*
|
|
523
|
+
* @module admin
|
|
524
|
+
* @since 0.1.0
|
|
525
|
+
*/
|
|
526
|
+
|
|
527
|
+
/** Component path for FormBuilderView */
|
|
528
|
+
declare const FORM_BUILDER_VIEW_PATH: ComponentPath;
|
|
529
|
+
/** Component path for SubmissionsFilter */
|
|
530
|
+
declare const SUBMISSIONS_FILTER_PATH: ComponentPath;
|
|
531
|
+
/**
|
|
532
|
+
* Register Form Builder admin components with the Nextly admin panel.
|
|
533
|
+
*
|
|
534
|
+
* @deprecated This function is no longer needed. Components are auto-registered
|
|
535
|
+
* when the admin detects the Form Builder plugin's component paths in collection configs.
|
|
536
|
+
*
|
|
537
|
+
* @example
|
|
538
|
+
* ```typescript
|
|
539
|
+
* // No manual registration needed! Just add the plugin to your config:
|
|
540
|
+
* export default defineConfig({
|
|
541
|
+
* plugins: [formBuilderPlugin.plugin],
|
|
542
|
+
* });
|
|
543
|
+
* ```
|
|
544
|
+
*/
|
|
545
|
+
declare function registerFormBuilderAdminComponents(): void;
|
|
546
|
+
|
|
547
|
+
export { AddFieldButton, type AddFieldButtonProps, DEFAULT_SETTINGS, FORM_BUILDER_VIEW_PATH, FieldEditor, FieldEditorPanel, type FieldEditorPanelProps, type FieldEditorProps, FieldLibrary, type FormBuilderActions, type FormBuilderContextValue, FormBuilderProvider, type FormBuilderProviderProps, type FormBuilderState, FormBuilderView, type FormBuilderViewProps, FormCanvas, type FormCanvasProps, FormFieldList, type FormFieldListProps, type FormNotification, FormNotificationsTab, FormPreview, type FormPreviewProps, type FormSettings, FormSettingsTab, SUBMISSIONS_FILTER_PATH, SortableFieldRow, type SortableFieldRowProps, SubmissionsFilter, type SubmissionsFilterProps, createFieldFromType, createNotification, generateFieldLabel, generateFieldName, registerFormBuilderAdminComponents, useFormBuilder, useOptionalFormBuilder };
|