@nextlyhq/plugin-form-builder 0.0.2-alpha.74 → 0.0.2-alpha.75
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 +2 -1
- package/dist/admin/index.d.ts +81 -65
- package/dist/admin/index.js +3459 -1457
- package/dist/admin/index.js.map +1 -1
- package/dist/{field-references-CtzGg51W.js → field-references-oCuFEwkr.js} +1256 -524
- package/dist/field-references-oCuFEwkr.js.map +1 -0
- package/dist/index.d.ts +11 -5
- package/dist/index.js +1893 -404
- package/dist/index.js.map +1 -1
- package/dist/{new-submissions-CzlhVGhH.d.ts → new-submissions-DGiIhdBF.d.ts} +96 -5
- package/package.json +10 -10
- package/dist/field-references-CtzGg51W.js.map +0 -1
package/README.md
CHANGED
|
@@ -66,7 +66,8 @@ import "@nextlyhq/plugin-form-builder/admin";
|
|
|
66
66
|
- **Admin routes:** `/admin/collections/forms` and `/admin/collections/form-submissions`
|
|
67
67
|
- **Collections:** `forms`, `form-submissions`
|
|
68
68
|
- **Form lifecycle states:** Draft, Published, Closed
|
|
69
|
-
- **
|
|
69
|
+
- **One response per person:** by email address, browser or network address, refused atomically by a keyed digest (the browser mode needs your form's script to send a token; see the docs)
|
|
70
|
+
- **Optional integrations:** email notifications, a `form.submission.created` webhook through Nextly's own webhooks, spam protection (honeypot, rate limit, and a reCAPTCHA v3 or Cloudflare Turnstile bot check verified on the server)
|
|
70
71
|
|
|
71
72
|
### Submission privacy
|
|
72
73
|
|
package/dist/admin/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { O as FormSettings, S as FormFieldTypeId, T as FormNotification, b as FormField, i as AnyFormField, r as NewSubmissionsData } from "../new-submissions-
|
|
2
|
-
import { ComponentPath, DocumentLockGates } from "@nextlyhq/plugin-sdk/admin";
|
|
1
|
+
import { O as FormSettings, S as FormFieldTypeId, T as FormNotification, b as FormField, i as AnyFormField, r as NewSubmissionsData } from "../new-submissions-DGiIhdBF.js";
|
|
2
|
+
import { ComponentPath, DocumentLockGates, FieldPickerChoice } from "@nextlyhq/plugin-sdk/admin";
|
|
3
3
|
import React, { JSX, ReactNode } from "react";
|
|
4
|
-
import {
|
|
4
|
+
import { FormFieldCatalogType } from "nextly/field-catalog";
|
|
5
5
|
interface FormBuilderViewProps {
|
|
6
6
|
id?: string;
|
|
7
7
|
entryId?: string;
|
|
@@ -14,6 +14,8 @@ interface FormBuilderViewProps {
|
|
|
14
14
|
slug?: string;
|
|
15
15
|
description?: string;
|
|
16
16
|
status?: "draft" | "published" | "closed";
|
|
17
|
+
/** When the form first went live: what fixes its ID. */
|
|
18
|
+
wentLiveAt?: string | null;
|
|
17
19
|
closedMessage?: string;
|
|
18
20
|
fields?: unknown[];
|
|
19
21
|
settings?: Record<string, unknown>;
|
|
@@ -24,8 +26,15 @@ interface FormBuilderViewProps {
|
|
|
24
26
|
*/
|
|
25
27
|
_rev?: string;
|
|
26
28
|
};
|
|
27
|
-
|
|
29
|
+
/**
|
|
30
|
+
* Saves the form in the host's own way, in place of the builder's request.
|
|
31
|
+
* The builder counts the form saved once this returns, or once the promise
|
|
32
|
+
* it may return settles without failing.
|
|
33
|
+
*/
|
|
34
|
+
onSave?: (data: unknown) => void | Promise<void>;
|
|
28
35
|
onSuccess?: (entry?: Record<string, unknown>) => void;
|
|
36
|
+
/** Called once the form has been deleted from the editor's More menu. */
|
|
37
|
+
onDelete?: () => void;
|
|
29
38
|
onCancel?: () => void;
|
|
30
39
|
/**
|
|
31
40
|
* What a colleague's claim on this form withholds, handed over by the admin
|
|
@@ -37,8 +46,14 @@ interface FormBuilderViewProps {
|
|
|
37
46
|
* it too.
|
|
38
47
|
*/
|
|
39
48
|
documentLock?: DocumentLockGates;
|
|
49
|
+
/**
|
|
50
|
+
* The page of the editor the address names (`"settings"` at
|
|
51
|
+
* `/admin/collections/forms/<id>/settings`); absent on the form's edit
|
|
52
|
+
* address, which opens Builder.
|
|
53
|
+
*/
|
|
54
|
+
view?: string;
|
|
40
55
|
}
|
|
41
|
-
export declare function FormBuilderView({ id, entryId, collection, collectionSlug, isCreating, initialData, onSave, onSuccess,
|
|
56
|
+
export declare function FormBuilderView({ id, entryId, collection, collectionSlug, isCreating, initialData, onSave, onSuccess, onDelete, documentLock, view }: FormBuilderViewProps): JSX.Element;
|
|
42
57
|
interface SubmissionRow {
|
|
43
58
|
id: string;
|
|
44
59
|
form: string | {
|
|
@@ -64,8 +79,13 @@ interface FormOption {
|
|
|
64
79
|
}
|
|
65
80
|
interface SubmissionsViewProps {
|
|
66
81
|
collectionSlug?: string;
|
|
82
|
+
/**
|
|
83
|
+
* Show only this form's submissions, with no choice of form: the list as a
|
|
84
|
+
* form's own Submissions tab draws it.
|
|
85
|
+
*/
|
|
86
|
+
formId?: string;
|
|
67
87
|
}
|
|
68
|
-
export declare function SubmissionsView({ collectionSlug }: SubmissionsViewProps): JSX.Element;
|
|
88
|
+
export declare function SubmissionsView({ collectionSlug, formId }: SubmissionsViewProps): JSX.Element;
|
|
69
89
|
interface SubmissionSheetProps {
|
|
70
90
|
submission: SubmissionRow;
|
|
71
91
|
form: FormOption;
|
|
@@ -76,17 +96,18 @@ interface SubmissionSheetProps {
|
|
|
76
96
|
onSave: (changes: Record<string, unknown>) => Promise<void>;
|
|
77
97
|
}
|
|
78
98
|
export declare function SubmissionSheet({ submission, form, canUpdate, onClose, onPrev, onNext, onSave }: SubmissionSheetProps): JSX.Element;
|
|
79
|
-
/** The card's rows,
|
|
80
|
-
export declare function NewSubmissionsCard({ data }: {
|
|
99
|
+
/** The card's rows: its reader's "Number of entries", the rows its `load` read. */
|
|
100
|
+
export declare function NewSubmissionsCard({ data, settings }: {
|
|
81
101
|
data: NewSubmissionsData;
|
|
102
|
+
/** The card's settings as its `load` read them; `limit` is its "Number of entries". */
|
|
103
|
+
settings?: Record<string, unknown>;
|
|
82
104
|
}): JSX.Element;
|
|
83
105
|
interface FieldCardsProps {
|
|
84
106
|
/**
|
|
85
107
|
* Form-surface types the host has NOT excluded (the plugin's field
|
|
86
108
|
* enable/disable option). `null` while the host configuration is still
|
|
87
|
-
* loading
|
|
88
|
-
*
|
|
89
|
-
* added.
|
|
109
|
+
* loading: Add field waits rather than offering the unfiltered set. Types
|
|
110
|
+
* outside this set stay editable on existing fields but cannot be added.
|
|
90
111
|
*/
|
|
91
112
|
enabledTypes: readonly FormFieldCatalogType[] | null;
|
|
92
113
|
/**
|
|
@@ -95,52 +116,23 @@ interface FieldCardsProps {
|
|
|
95
116
|
* contributed types.
|
|
96
117
|
*/
|
|
97
118
|
disabledFieldTypes?: ReadonlySet<string>;
|
|
98
|
-
/** Creates a field of the given type and returns it (context helper). */
|
|
99
|
-
onAddField: (type: FormFieldTypeId) => void;
|
|
100
|
-
}
|
|
101
|
-
export declare function FieldCards({ enabledTypes, disabledFieldTypes, onAddField }: FieldCardsProps): JSX.Element;
|
|
102
|
-
interface AddFieldDialogProps {
|
|
103
|
-
open: boolean;
|
|
104
|
-
onOpenChange: (open: boolean) => void;
|
|
105
119
|
/**
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
*
|
|
120
|
+
* Creates and selects a field of the chosen type. The picker's whole choice
|
|
121
|
+
* comes second (the label the person typed and the name it gives), so a host
|
|
122
|
+
* written for the type alone keeps working and one that wants the label
|
|
123
|
+
* reads it there. The third is where in the list it goes, when it was added
|
|
124
|
+
* between two rows or below one; absent for the end.
|
|
110
125
|
*/
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
/** All fields in the form (for conditional logic references) */
|
|
120
|
-
allFields: AnyFormField[];
|
|
121
|
-
/** Callback when field is updated */
|
|
122
|
-
onUpdate: (updates: Partial<AnyFormField>) => void;
|
|
126
|
+
onAddField: (type: FormFieldTypeId, choice?: FieldPickerChoice, index?: number) => void;
|
|
127
|
+
/**
|
|
128
|
+
* Where the selected field's settings dock from 1024px: `"beside"` the list
|
|
129
|
+
* (the default, for a list drawn on its own), or by the `"host"` page,
|
|
130
|
+
* which draws `FieldInspector` against the window's edge itself. Below
|
|
131
|
+
* 1024px they open under the row either way.
|
|
132
|
+
*/
|
|
133
|
+
dockedSettings?: "beside" | "host";
|
|
123
134
|
}
|
|
124
|
-
|
|
125
|
-
* FieldEditor - Field properties configuration panel
|
|
126
|
-
*
|
|
127
|
-
* Provides a tabbed interface for editing field properties:
|
|
128
|
-
* - General: name, label, placeholder, help text, required, width, type-specific options
|
|
129
|
-
* - Validation: error messages, min/max length, patterns, etc.
|
|
130
|
-
* - Conditional: show/hide logic based on other field values
|
|
131
|
-
*
|
|
132
|
-
* @example
|
|
133
|
-
* ```tsx
|
|
134
|
-
* <FieldEditor
|
|
135
|
-
* field={selectedField}
|
|
136
|
-
* allFields={allFields}
|
|
137
|
-
* onUpdate={handleUpdate}
|
|
138
|
-
* onDelete={handleDelete}
|
|
139
|
-
* onDuplicate={handleDuplicate}
|
|
140
|
-
* />
|
|
141
|
-
* ```
|
|
142
|
-
*/
|
|
143
|
-
export declare function FieldEditor({ field, allFields, onUpdate }: FieldEditorProps): JSX.Element;
|
|
135
|
+
export declare function FieldCards({ enabledTypes, disabledFieldTypes, onAddField, dockedSettings }: FieldCardsProps): JSX.Element;
|
|
144
136
|
interface FormPreviewProps {
|
|
145
137
|
/** Array of form fields to preview (built-in or plugin-contributed). */
|
|
146
138
|
fields: AnyFormField[];
|
|
@@ -152,12 +144,23 @@ interface FormPreviewProps {
|
|
|
152
144
|
};
|
|
153
145
|
}
|
|
154
146
|
export declare function FormPreview({ fields, formData }: FormPreviewProps): JSX.Element;
|
|
147
|
+
/**
|
|
148
|
+
* Generate a readable unique field name: the type itself for the first
|
|
149
|
+
* field of that type, then a numeric suffix (`email`, `email_2`, ...).
|
|
150
|
+
* Names key submission data, so they should read like keys a developer
|
|
151
|
+
* would have chosen, not timestamps.
|
|
152
|
+
*/
|
|
153
|
+
export declare function generateFieldName(type: FormFieldTypeId, existingNames?: readonly string[]): string;
|
|
155
154
|
interface FormBuilderState {
|
|
156
155
|
/** Form fields array */
|
|
157
156
|
fields: AnyFormField[];
|
|
158
157
|
/** Currently selected field ID (name) */
|
|
159
158
|
selectedFieldId: string | null;
|
|
160
|
-
/**
|
|
159
|
+
/**
|
|
160
|
+
* Active tab: builder, preview, settings, or notifications.
|
|
161
|
+
* @deprecated The editor shows the page its address names; this is no
|
|
162
|
+
* longer what it shows, and is kept for hosts that read it.
|
|
163
|
+
*/
|
|
161
164
|
activeTab: "builder" | "preview" | "settings" | "notifications";
|
|
162
165
|
/** Whether form has unsaved changes */
|
|
163
166
|
isDirty: boolean;
|
|
@@ -191,7 +194,10 @@ interface FormBuilderActions {
|
|
|
191
194
|
duplicateField: (fieldName: string) => void;
|
|
192
195
|
/** Select a field */
|
|
193
196
|
selectField: (fieldName: string | null) => void;
|
|
194
|
-
/**
|
|
197
|
+
/**
|
|
198
|
+
* Set active tab.
|
|
199
|
+
* @deprecated The editor's tabs are links to each page's address.
|
|
200
|
+
*/
|
|
195
201
|
setActiveTab: (tab: "builder" | "preview" | "settings" | "notifications") => void;
|
|
196
202
|
/** Update form metadata */
|
|
197
203
|
updateFormData: (updates: Partial<FormBuilderState["formData"]>) => void;
|
|
@@ -219,6 +225,8 @@ interface FormBuilderProviderProps {
|
|
|
219
225
|
slug?: string;
|
|
220
226
|
description?: string;
|
|
221
227
|
status?: "draft" | "published" | "closed";
|
|
228
|
+
/** When the form first went live, as the server stamped it. */
|
|
229
|
+
wentLiveAt?: string | null;
|
|
222
230
|
closedMessage?: string;
|
|
223
231
|
fields?: AnyFormField[];
|
|
224
232
|
settings?: Partial<FormSettings>;
|
|
@@ -242,13 +250,6 @@ interface FormBuilderProviderProps {
|
|
|
242
250
|
export declare const DEFAULT_SETTINGS: FormSettings;
|
|
243
251
|
/** Create a new notification rule with default values */
|
|
244
252
|
export declare function createNotification(): FormNotification;
|
|
245
|
-
/**
|
|
246
|
-
* Generate a readable unique field name: the type itself for the first
|
|
247
|
-
* field of that type, then a numeric suffix (`email`, `email_2`, ...).
|
|
248
|
-
* Names key submission data, so they should read like keys a developer
|
|
249
|
-
* would have chosen, not timestamps.
|
|
250
|
-
*/
|
|
251
|
-
export declare function generateFieldName(type: FormFieldTypeId, existingNames?: readonly string[]): string;
|
|
252
253
|
/**
|
|
253
254
|
* Generate a human-readable label from field type, using the shared catalog
|
|
254
255
|
* so a new field's default label matches what the picker called the type. A
|
|
@@ -310,7 +311,22 @@ export declare function useFormBuilder(): FormBuilderContextValue;
|
|
|
310
311
|
* @returns Form builder context value or null
|
|
311
312
|
*/
|
|
312
313
|
export declare function useOptionalFormBuilder(): FormBuilderContextValue | null;
|
|
313
|
-
|
|
314
|
+
type BotProvider = "recaptcha" | "turnstile";
|
|
315
|
+
/** What the plugin's options say about bot checks and the rate limit. */
|
|
316
|
+
interface BotCheckSiteDefaults {
|
|
317
|
+
/** The provider "Site default" resolves to, or null for none. */
|
|
318
|
+
botCheckDefault?: BotProvider | null;
|
|
319
|
+
/** Which providers have their keys set. */
|
|
320
|
+
botChecks?: Record<BotProvider, {
|
|
321
|
+
secret: boolean;
|
|
322
|
+
siteKey: boolean;
|
|
323
|
+
}>;
|
|
324
|
+
rateLimit?: {
|
|
325
|
+
maxSubmissions: number;
|
|
326
|
+
windowMs: number;
|
|
327
|
+
} | null;
|
|
328
|
+
}
|
|
329
|
+
interface SpamDefaults extends BotCheckSiteDefaults {
|
|
314
330
|
honeypot?: boolean;
|
|
315
331
|
recaptchaEnabled?: boolean;
|
|
316
332
|
}
|
|
@@ -351,5 +367,5 @@ export declare function FormNotificationsTab({ defaults }: FormNotificationsTabP
|
|
|
351
367
|
export declare const FORM_BUILDER_VIEW_PATH: ComponentPath;
|
|
352
368
|
/** Component path for SubmissionsView */
|
|
353
369
|
export declare const SUBMISSIONS_VIEW_PATH: ComponentPath;
|
|
354
|
-
export type {
|
|
370
|
+
export type { FieldCardsProps, FormBuilderActions, FormBuilderContextValue, FormBuilderProviderProps, FormBuilderState, FormBuilderViewProps, FormNotification, FormPreviewProps, FormSettings };
|
|
355
371
|
//# sourceMappingURL=index.d.ts.map
|