@nextlyhq/plugin-form-builder 0.0.2-alpha.60 → 0.0.2-alpha.64

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
@@ -1,6 +1,6 @@
1
1
  # @nextlyhq/plugin-form-builder
2
2
 
3
- Drag-and-drop form builder plugin for Nextly. Build forms visually, collect submissions, and filter them by form. _Coming soon in beta._
3
+ Drag-and-drop form builder plugin for Nextly. Build forms visually, collect submissions, and filter them by form.
4
4
 
5
5
  <p align="center">
6
6
  <a href="https://www.npmjs.com/package/@nextlyhq/plugin-form-builder"><img alt="npm" src="https://img.shields.io/npm/v/@nextlyhq/plugin-form-builder?style=flat-square&label=npm&color=cb3837" /></a>
@@ -8,11 +8,10 @@ Drag-and-drop form builder plugin for Nextly. Build forms visually, collect subm
8
8
  <a href="https://nextlyhq.com/docs"><img alt="Status" src="https://img.shields.io/badge/status-alpha-orange?style=flat-square" /></a>
9
9
  </p>
10
10
 
11
- > [!WARNING]
12
- > **Coming soon in beta. Plugins are not ready for use yet.** Public plugin support, including stable APIs, the official plugin gallery, and documentation guarantees, lands at the Nextly **beta** release. This package is published for early exploration only. Surfaces, names, and behaviour will change without notice. Do not rely on plugins for production or serious development work. Wait for the beta release announcement before integrating plugins into your project.
13
-
14
11
  > [!IMPORTANT]
15
- > Nextly is in alpha. APIs may change before 1.0. Pin exact versions in production.
12
+ > Nextly is in alpha. APIs may change before 1.0 — pin exact versions in production.
13
+ > See the [plugin stability ladder](https://nextlyhq.com/docs/plugins/stability) for
14
+ > which plugin surfaces are stable and which are experimental.
16
15
 
17
16
  ## What it is
18
17
 
@@ -1,6 +1,6 @@
1
- import { ComponentPath } from '@nextlyhq/plugin-sdk/admin';
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-DuEFdLNU.js';
3
+ import { q as FormField, s as FormFieldTypeId, A as AnyFormField, b as FormSettings, v as FormNotification } from '../types-hLfLe81K.js';
4
4
  import { FormFieldCatalogType, FieldTypeCatalogEntry } from 'nextly/field-catalog';
5
5
  import { ReactNode } from 'react';
6
6
  import 'nextly';
@@ -17,6 +17,7 @@ interface FormBuilderViewProps {
17
17
  slug?: string;
18
18
  description?: string;
19
19
  status?: "draft" | "published" | "closed";
20
+ closedMessage?: string;
20
21
  fields?: unknown[];
21
22
  settings?: Record<string, unknown>;
22
23
  notifications?: unknown[];
@@ -24,8 +25,18 @@ interface FormBuilderViewProps {
24
25
  onSave?: (data: unknown) => void;
25
26
  onSuccess?: (entry?: Record<string, unknown>) => void;
26
27
  onCancel?: () => void;
28
+ /**
29
+ * What a colleague's claim on this form withholds, handed over by the admin
30
+ * page that renders this view.
31
+ *
32
+ * The strip above this builder says in words that unsaved changes cannot be
33
+ * saved while someone else holds the document. Committing anyway would make
34
+ * that sentence false and would overwrite the holder's row, so the save reads
35
+ * it too.
36
+ */
37
+ documentLock?: DocumentLockGates;
27
38
  }
28
- declare function FormBuilderView({ id, entryId, collection, collectionSlug, isCreating, initialData, onSave, onSuccess, onCancel, }: FormBuilderViewProps): react_jsx_runtime.JSX.Element;
39
+ declare function FormBuilderView({ id, entryId, collection, collectionSlug, isCreating, initialData, onSave, onSuccess, onCancel, documentLock, }: FormBuilderViewProps): react_jsx_runtime.JSX.Element;
29
40
 
30
41
  interface SubmissionRow {
31
42
  id: string;
@@ -156,6 +167,8 @@ interface FormBuilderState {
156
167
  slug: string;
157
168
  description?: string;
158
169
  status: "draft" | "published" | "closed";
170
+ /** What a closed form tells a visitor who reaches it. */
171
+ closedMessage?: string;
159
172
  };
160
173
  /** Form settings */
161
174
  settings: FormSettings;
@@ -206,12 +219,24 @@ interface FormBuilderProviderProps {
206
219
  slug?: string;
207
220
  description?: string;
208
221
  status?: "draft" | "published" | "closed";
222
+ closedMessage?: string;
209
223
  fields?: AnyFormField[];
210
224
  settings?: Partial<FormSettings>;
211
225
  notifications?: FormNotification[];
212
226
  };
213
227
  /** Child components */
214
228
  children: ReactNode;
229
+ /**
230
+ * The document belongs to someone else right now, so nothing here may change
231
+ * it.
232
+ *
233
+ * Held here rather than at each control because the builder has dozens of
234
+ * them across four tabs, and a rule spelled at every one is a rule one new
235
+ * control forgets. Reading is untouched: the editor still browses fields,
236
+ * switches tabs and opens settings, which is exactly what the strip above
237
+ * offers them.
238
+ */
239
+ readOnly?: boolean;
215
240
  }
216
241
  /** Default form settings (the canonical defaults from the settings reader) */
217
242
  declare const DEFAULT_SETTINGS: FormSettings;
@@ -247,7 +272,7 @@ declare function createFieldFromType(type: FormFieldTypeId, existingNames?: read
247
272
  * </FormBuilderProvider>
248
273
  * ```
249
274
  */
250
- declare function FormBuilderProvider({ initialData, children, }: FormBuilderProviderProps): react_jsx_runtime.JSX.Element;
275
+ declare function FormBuilderProvider({ initialData, children, readOnly, }: FormBuilderProviderProps): react_jsx_runtime.JSX.Element;
251
276
  /**
252
277
  * useFormBuilder - Access form builder context
253
278
  *
@@ -293,8 +318,20 @@ interface SpamDefaults {
293
318
  interface FormSettingsTabProps {
294
319
  /** Plugin-level spam defaults (from builder-config); null while loading. */
295
320
  spamDefaults: SpamDefaults | null;
321
+ /**
322
+ * Collections a form may redirect to (from builder-config); null while
323
+ * loading. Empty means the site configured none, and the option is not
324
+ * offered — choosing it could only ever produce a form with no destination.
325
+ */
326
+ redirectCollections: string[] | null;
327
+ /**
328
+ * The configuration request failed, as distinct from returning nothing. An
329
+ * empty list is a valid answer; a failure is not an answer at all, and
330
+ * saying "no collection is configured" on a 403 states something false.
331
+ */
332
+ redirectConfigFailed: boolean;
296
333
  }
297
- declare function FormSettingsTab({ spamDefaults }: FormSettingsTabProps): react_jsx_runtime.JSX.Element;
334
+ declare function FormSettingsTab({ spamDefaults, redirectCollections, redirectConfigFailed, }: FormSettingsTabProps): react_jsx_runtime.JSX.Element;
298
335
 
299
336
  /** Host-level notification defaults surfaced by the builder-config route. */
300
337
  interface NotificationDefaults {