@nextlyhq/plugin-form-builder 0.0.2-alpha.66 → 0.0.2-alpha.68

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/README.md CHANGED
@@ -60,7 +60,7 @@ import "@nextlyhq/plugin-form-builder/admin";
60
60
  - **Admin routes:** `/admin/collections/forms` and `/admin/collections/form-submissions`
61
61
  - **Collections:** `forms`, `form-submissions`
62
62
  - **Form lifecycle states:** Draft, Published, Closed
63
- - **Optional integrations:** email notifications, webhook delivery on submission, spam protection (honeypot, rate limit, reCAPTCHA v3)
63
+ - **Optional integrations:** email notifications, a `form.submission.created` webhook through Nextly's own webhooks, spam protection (honeypot, rate limit, reCAPTCHA v3)
64
64
 
65
65
  ### Submission privacy
66
66
 
@@ -100,15 +100,15 @@ See the [Field types reference](https://nextlyhq.com/docs/plugins/form-builder#f
100
100
  - Server helpers: `submitForm`, `validateSubmission`, `getFormSubmissionStats`, `createFormConfig`, `validateFormConfig`, `assertValidFormConfig`
101
101
  - Export utilities: `exportToCSV`, `exportToJSON`, `exportAndDownload`, `downloadFile`, `generateExportFilename`
102
102
  - Collections: `formsCollection`, `submissionsCollection`
103
- - Type exports: `FormDocument`, `SubmissionDocument`, `FormSubmission`, `FormNotification`, `EmailConfig`, `WebhookConfig`, `WebhookEvent`, `FormFieldOption`
103
+ - Type exports: `FormDocument`, `SubmissionDocument`, `FormSubmission`, `FormNotification`, `EmailConfig`, `FormFieldOption`
104
104
 
105
105
  ## Compatibility
106
106
 
107
- | Tool | Version |
108
- | ----------------- | ------- |
109
- | Node.js | 20+ |
110
- | `nextly` | 0.0.x |
111
- | `@nextlyhq/admin` | 0.0.x |
107
+ | Tool | Version |
108
+ | ----------------- | --------------------- |
109
+ | Node.js | 20.19+, 22.12+ or 24+ |
110
+ | `nextly` | 0.0.x |
111
+ | `@nextlyhq/admin` | 0.0.x |
112
112
 
113
113
  Plugins can break across minor versions during alpha. Pin exact versions of `nextly`, `@nextlyhq/admin`, and this plugin together.
114
114
 
@@ -1,6 +1,6 @@
1
1
  import { DocumentLockGates, ComponentPath } from '@nextlyhq/plugin-sdk/admin';
2
2
  import * as react_jsx_runtime from 'react/jsx-runtime';
3
- import { q as FormField, s as FormFieldTypeId, A as AnyFormField, b as FormSettings, v as FormNotification } from '../types-hLfLe81K.js';
3
+ import { q as FormField, s as FormFieldTypeId, A as AnyFormField, b as FormSettings, v as FormNotification } from '../types-Bo4lk9BD.js';
4
4
  import { FormFieldCatalogType, FieldTypeCatalogEntry } from 'nextly/field-catalog';
5
5
  import { ReactNode } from 'react';
6
6
  import 'nextly';
@@ -9,7 +9,7 @@ import {
9
9
  normalizeFormSettings,
10
10
  parseFieldRef,
11
11
  parseRedirectReference
12
- } from "../chunk-VIGKSRSH.js";
12
+ } from "../chunk-X5WLJLAR.js";
13
13
 
14
14
  // src/admin/index.ts
15
15
  import {
@@ -894,7 +894,7 @@ import {
894
894
  } from "@nextlyhq/ui";
895
895
  import { useQueryClient } from "@tanstack/react-query";
896
896
  import { FORM_FIELD_TYPE_CATALOG as FORM_FIELD_TYPE_CATALOG3 } from "nextly/field-catalog";
897
- import { useCallback as useCallback7, useEffect as useEffect5, useRef as useRef2, useState as useState10 } from "react";
897
+ import { useCallback as useCallback7, useEffect as useEffect5, useRef as useRef3, useState as useState10 } from "react";
898
898
 
899
899
  // src/admin/components/builder/FieldCards.tsx
900
900
  import {
@@ -926,7 +926,7 @@ import {
926
926
  } from "@nextlyhq/ui";
927
927
  import * as Lucide from "lucide-react";
928
928
  import { FORM_FIELD_TYPE_CATALOG as FORM_FIELD_TYPE_CATALOG2 } from "nextly/field-catalog";
929
- import { useCallback as useCallback5, useMemo as useMemo5, useState as useState6 } from "react";
929
+ import { useCallback as useCallback5, useMemo as useMemo5, useRef as useRef2, useState as useState6 } from "react";
930
930
 
931
931
  // src/admin/context/FormBuilderContext.tsx
932
932
  import { FORM_FIELD_TYPE_CATALOG } from "nextly/field-catalog";
@@ -1066,7 +1066,7 @@ function FormBuilderProvider({
1066
1066
  setFieldsState(
1067
1067
  (prev) => prev.map((f) => f.name === fieldName ? { ...f, ...updates } : f)
1068
1068
  );
1069
- if (updates.name && updates.name !== fieldName) {
1069
+ if (updates.name !== void 0 && updates.name !== fieldName) {
1070
1070
  setSelectedFieldId(updates.name);
1071
1071
  }
1072
1072
  setIsDirty(true);
@@ -2303,6 +2303,29 @@ function FieldCards({
2303
2303
  moveField
2304
2304
  } = useFormBuilder();
2305
2305
  const [isAddOpen, setIsAddOpen] = useState6(false);
2306
+ const cardKeysRef = useRef2(/* @__PURE__ */ new Map());
2307
+ const nextCardKeyRef = useRef2(0);
2308
+ const cardKeyFor = (name) => {
2309
+ let key = cardKeysRef.current.get(name);
2310
+ if (key === void 0) {
2311
+ key = `card-${++nextCardKeyRef.current}`;
2312
+ cardKeysRef.current.set(name, key);
2313
+ }
2314
+ return key;
2315
+ };
2316
+ const handleUpdate = useCallback5(
2317
+ (field, updates) => {
2318
+ if (updates.name !== void 0 && updates.name !== field.name) {
2319
+ const key = cardKeysRef.current.get(field.name);
2320
+ if (key !== void 0) {
2321
+ cardKeysRef.current.delete(field.name);
2322
+ cardKeysRef.current.set(updates.name, key);
2323
+ }
2324
+ }
2325
+ updateField(field.name, updates);
2326
+ },
2327
+ [updateField]
2328
+ );
2306
2329
  const sensors = useSensors(
2307
2330
  useSensor(PointerSensor, { activationConstraint: { distance: 4 } }),
2308
2331
  useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates })
@@ -2371,12 +2394,12 @@ function FieldCards({
2371
2394
  deleteBlockers: (referenceMap.get(field.name) ?? []).map(
2372
2395
  (ref) => ref.label
2373
2396
  ),
2374
- onUpdate: (updates) => updateField(field.name, updates),
2397
+ onUpdate: (updates) => handleUpdate(field, updates),
2375
2398
  onDuplicate: () => duplicateField(field.name),
2376
2399
  onDelete: () => deleteField(field.name),
2377
2400
  onMove: (direction) => moveField(index, index + direction)
2378
2401
  }
2379
- ) }, field.name)) })
2402
+ ) }, cardKeyFor(field.name))) })
2380
2403
  }
2381
2404
  )
2382
2405
  }
@@ -4506,7 +4529,7 @@ function FormBuilderViewInner({
4506
4529
  cancelled = true;
4507
4530
  };
4508
4531
  }, []);
4509
- const seededRef = useRef2(false);
4532
+ const seededRef = useRef3(false);
4510
4533
  useEffect5(() => {
4511
4534
  if (!isCreating || notificationDefaults === null || seededRef.current) {
4512
4535
  return;