form-page-builder 0.1.0 → 2.0.0
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 +0 -0
- package/README.md +183 -9
- package/dist/index.cjs +1086 -816
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +129 -32
- package/dist/index.d.ts +129 -32
- package/dist/index.js +1083 -814
- package/dist/index.js.map +1 -1
- package/package.json +12 -4
package/dist/index.d.cts
CHANGED
|
@@ -28,13 +28,15 @@ declare const ICON_LIBRARY: {
|
|
|
28
28
|
};
|
|
29
29
|
type IconKey = keyof typeof ICON_LIBRARY;
|
|
30
30
|
|
|
31
|
-
type FieldType = "paragraph" | "image" | "input" | "textarea" | "select" | "radio" | "checkboxGroup" | "checkbox" | "toggle";
|
|
31
|
+
type FieldType = "paragraph" | "image" | "button" | "input" | "textarea" | "select" | "radio" | "checkboxGroup" | "checkbox" | "toggle";
|
|
32
32
|
|
|
33
33
|
declare const CHROME: {
|
|
34
34
|
en: {
|
|
35
35
|
contentBlocks: string;
|
|
36
36
|
formFields: string;
|
|
37
37
|
addingTo: string;
|
|
38
|
+
paletteTabBlocks: string;
|
|
39
|
+
paletteTabDesign: string;
|
|
38
40
|
properties: string;
|
|
39
41
|
selectFieldHint: string;
|
|
40
42
|
label: string;
|
|
@@ -80,14 +82,14 @@ declare const CHROME: {
|
|
|
80
82
|
build: string;
|
|
81
83
|
preview: string;
|
|
82
84
|
newForm: string;
|
|
83
|
-
|
|
85
|
+
templates: string;
|
|
84
86
|
save: string;
|
|
85
87
|
viewJson: string;
|
|
86
88
|
saving: string;
|
|
87
89
|
saved: string;
|
|
88
90
|
saveFailed: string;
|
|
89
91
|
startNewForm: string;
|
|
90
|
-
|
|
92
|
+
openTemplatesTitle: string;
|
|
91
93
|
saveToLibraryTitle: string;
|
|
92
94
|
sectionTitlePlaceholder: (n: number) => string;
|
|
93
95
|
noFieldsInSection: string;
|
|
@@ -101,22 +103,17 @@ declare const CHROME: {
|
|
|
101
103
|
formJson: string;
|
|
102
104
|
copy: string;
|
|
103
105
|
copied: string;
|
|
104
|
-
|
|
106
|
+
noTemplates: string;
|
|
105
107
|
updated: string;
|
|
106
108
|
open: string;
|
|
107
109
|
saveForm: string;
|
|
108
110
|
formName: string;
|
|
109
111
|
saveToLibrary: string;
|
|
110
112
|
loadingDraft: string;
|
|
113
|
+
templatesLimitReached: string;
|
|
111
114
|
current: string;
|
|
112
115
|
customColor: string;
|
|
113
116
|
fieldsCount: (n: number) => string;
|
|
114
|
-
formSettings: string;
|
|
115
|
-
submitLabel: string;
|
|
116
|
-
submitMode: string;
|
|
117
|
-
combined: string;
|
|
118
|
-
perSection: string;
|
|
119
|
-
settings: string;
|
|
120
117
|
fieldTypeInput: string;
|
|
121
118
|
fieldTypeTextarea: string;
|
|
122
119
|
fieldTypeSelect: string;
|
|
@@ -126,6 +123,7 @@ declare const CHROME: {
|
|
|
126
123
|
fieldTypeToggle: string;
|
|
127
124
|
fieldTypeParagraph: string;
|
|
128
125
|
fieldTypeImage: string;
|
|
126
|
+
fieldTypeButton: string;
|
|
129
127
|
subtypeText: string;
|
|
130
128
|
subtypeEmail: string;
|
|
131
129
|
subtypePhone: string;
|
|
@@ -138,8 +136,17 @@ declare const CHROME: {
|
|
|
138
136
|
shapeBanner: string;
|
|
139
137
|
tagBody: string;
|
|
140
138
|
tagCaption: string;
|
|
141
|
-
|
|
142
|
-
|
|
139
|
+
buttonText: string;
|
|
140
|
+
buttonActionTitle: string;
|
|
141
|
+
buttonAction: string;
|
|
142
|
+
actionLink: string;
|
|
143
|
+
actionSubmit: string;
|
|
144
|
+
openIn: string;
|
|
145
|
+
sameTab: string;
|
|
146
|
+
newTab: string;
|
|
147
|
+
submitScope: string;
|
|
148
|
+
thisSection: string;
|
|
149
|
+
wholeForm: string;
|
|
143
150
|
buttonSize: string;
|
|
144
151
|
theme: string;
|
|
145
152
|
primaryColor: string;
|
|
@@ -164,6 +171,8 @@ declare const CHROME: {
|
|
|
164
171
|
contentBlocks: string;
|
|
165
172
|
formFields: string;
|
|
166
173
|
addingTo: string;
|
|
174
|
+
paletteTabBlocks: string;
|
|
175
|
+
paletteTabDesign: string;
|
|
167
176
|
properties: string;
|
|
168
177
|
selectFieldHint: string;
|
|
169
178
|
label: string;
|
|
@@ -209,14 +218,14 @@ declare const CHROME: {
|
|
|
209
218
|
build: string;
|
|
210
219
|
preview: string;
|
|
211
220
|
newForm: string;
|
|
212
|
-
|
|
221
|
+
templates: string;
|
|
213
222
|
save: string;
|
|
214
223
|
viewJson: string;
|
|
215
224
|
saving: string;
|
|
216
225
|
saved: string;
|
|
217
226
|
saveFailed: string;
|
|
218
227
|
startNewForm: string;
|
|
219
|
-
|
|
228
|
+
openTemplatesTitle: string;
|
|
220
229
|
saveToLibraryTitle: string;
|
|
221
230
|
sectionTitlePlaceholder: (n: number) => string;
|
|
222
231
|
noFieldsInSection: string;
|
|
@@ -230,22 +239,17 @@ declare const CHROME: {
|
|
|
230
239
|
formJson: string;
|
|
231
240
|
copy: string;
|
|
232
241
|
copied: string;
|
|
233
|
-
|
|
242
|
+
noTemplates: string;
|
|
234
243
|
updated: string;
|
|
235
244
|
open: string;
|
|
236
245
|
saveForm: string;
|
|
237
246
|
formName: string;
|
|
238
247
|
saveToLibrary: string;
|
|
239
248
|
loadingDraft: string;
|
|
249
|
+
templatesLimitReached: string;
|
|
240
250
|
current: string;
|
|
241
251
|
customColor: string;
|
|
242
252
|
fieldsCount: (n: number) => string;
|
|
243
|
-
formSettings: string;
|
|
244
|
-
submitLabel: string;
|
|
245
|
-
submitMode: string;
|
|
246
|
-
combined: string;
|
|
247
|
-
perSection: string;
|
|
248
|
-
settings: string;
|
|
249
253
|
fieldTypeInput: string;
|
|
250
254
|
fieldTypeTextarea: string;
|
|
251
255
|
fieldTypeSelect: string;
|
|
@@ -255,6 +259,7 @@ declare const CHROME: {
|
|
|
255
259
|
fieldTypeToggle: string;
|
|
256
260
|
fieldTypeParagraph: string;
|
|
257
261
|
fieldTypeImage: string;
|
|
262
|
+
fieldTypeButton: string;
|
|
258
263
|
subtypeText: string;
|
|
259
264
|
subtypeEmail: string;
|
|
260
265
|
subtypePhone: string;
|
|
@@ -267,8 +272,17 @@ declare const CHROME: {
|
|
|
267
272
|
shapeBanner: string;
|
|
268
273
|
tagBody: string;
|
|
269
274
|
tagCaption: string;
|
|
270
|
-
|
|
271
|
-
|
|
275
|
+
buttonText: string;
|
|
276
|
+
buttonActionTitle: string;
|
|
277
|
+
buttonAction: string;
|
|
278
|
+
actionLink: string;
|
|
279
|
+
actionSubmit: string;
|
|
280
|
+
openIn: string;
|
|
281
|
+
sameTab: string;
|
|
282
|
+
newTab: string;
|
|
283
|
+
submitScope: string;
|
|
284
|
+
thisSection: string;
|
|
285
|
+
wholeForm: string;
|
|
272
286
|
buttonSize: string;
|
|
273
287
|
theme: string;
|
|
274
288
|
primaryColor: string;
|
|
@@ -331,6 +345,8 @@ interface LanguageOption {
|
|
|
331
345
|
label: string;
|
|
332
346
|
}
|
|
333
347
|
|
|
348
|
+
type ContentBlockType = "paragraph" | "image" | "button";
|
|
349
|
+
type InputFieldType = "input" | "textarea" | "select" | "radio" | "checkboxGroup" | "checkbox" | "toggle";
|
|
334
350
|
interface LocalizedString {
|
|
335
351
|
en: string;
|
|
336
352
|
[lang: string]: string | undefined;
|
|
@@ -416,7 +432,17 @@ interface ImageField extends BaseField {
|
|
|
416
432
|
link: string;
|
|
417
433
|
shape: "square" | "circle" | "banner";
|
|
418
434
|
}
|
|
419
|
-
|
|
435
|
+
interface ButtonField extends BaseField {
|
|
436
|
+
type: "button";
|
|
437
|
+
action: "link" | "submit";
|
|
438
|
+
buttonStyle: SubmitStyle;
|
|
439
|
+
/** Used when `action === "link"`. */
|
|
440
|
+
href: string;
|
|
441
|
+
target: "_self" | "_blank";
|
|
442
|
+
/** Used when `action === "submit"`. */
|
|
443
|
+
submitScope: "section" | "form";
|
|
444
|
+
}
|
|
445
|
+
type FormField = InputField | TextareaField | SelectField | RadioField | CheckboxGroupField | CheckboxField | ToggleField | ParagraphField | ImageField | ButtonField;
|
|
420
446
|
/**
|
|
421
447
|
* Flat, fully-optional patch type for updateField/updateOption call sites.
|
|
422
448
|
* A strict `Partial<FormField>` doesn't typecheck for cross-type shallow
|
|
@@ -450,6 +476,11 @@ interface FieldPatch {
|
|
|
450
476
|
alt?: LocalizedString;
|
|
451
477
|
link?: string;
|
|
452
478
|
shape?: ImageField["shape"];
|
|
479
|
+
action?: ButtonField["action"];
|
|
480
|
+
buttonStyle?: SubmitStyle;
|
|
481
|
+
href?: string;
|
|
482
|
+
target?: ButtonField["target"];
|
|
483
|
+
submitScope?: ButtonField["submitScope"];
|
|
453
484
|
}
|
|
454
485
|
interface SubmitStyle {
|
|
455
486
|
color: string;
|
|
@@ -460,20 +491,18 @@ interface Section {
|
|
|
460
491
|
title: LocalizedString;
|
|
461
492
|
background: string;
|
|
462
493
|
collapsed: boolean;
|
|
463
|
-
submitStyle: SubmitStyle | null;
|
|
464
494
|
fields: FormField[];
|
|
465
495
|
}
|
|
466
496
|
interface DocumentFields {
|
|
467
497
|
title: LocalizedString;
|
|
468
|
-
submitLabel: LocalizedString;
|
|
469
|
-
submitMode: "combined" | "perSection";
|
|
470
|
-
submitStyle: SubmitStyle;
|
|
471
498
|
themeOverrides: ThemeOverrides;
|
|
472
499
|
sections: Section[];
|
|
473
500
|
}
|
|
474
501
|
/** Shape used only for the "View JSON" export (stamped with a version). */
|
|
475
502
|
interface FormDocument extends DocumentFields {
|
|
476
|
-
version:
|
|
503
|
+
version: 5;
|
|
504
|
+
/** Fully resolved theme (DEFAULT_THEME merged with `themeOverrides`) — lets a host re-render this document's styling without needing its own copy of the defaults. */
|
|
505
|
+
theme: Theme;
|
|
477
506
|
}
|
|
478
507
|
interface SavedFormMeta {
|
|
479
508
|
id: string;
|
|
@@ -511,24 +540,92 @@ interface StorageAdapter {
|
|
|
511
540
|
set(key: string, value: string): Promise<void>;
|
|
512
541
|
delete(key: string): Promise<void>;
|
|
513
542
|
}
|
|
543
|
+
interface SubmitPayload {
|
|
544
|
+
/** id of the button field that triggered this submission. */
|
|
545
|
+
buttonId: string;
|
|
546
|
+
/** Whether the triggering button's scope was the whole form or just its own section. */
|
|
547
|
+
scope: "form" | "section";
|
|
548
|
+
/** Set when `scope === "section"`. */
|
|
549
|
+
sectionId?: string;
|
|
550
|
+
/** fieldId -> raw value, scoped to whatever was just submitted (the whole form for "combined", one section for "section"). */
|
|
551
|
+
values: Record<string, unknown>;
|
|
552
|
+
/** Section-wise breakdown of the *entire* form, regardless of scope. */
|
|
553
|
+
sections: {
|
|
554
|
+
sectionId: string;
|
|
555
|
+
values: Record<string, unknown>;
|
|
556
|
+
}[];
|
|
557
|
+
/** Flattened fieldId -> raw value across every section, for convenience. */
|
|
558
|
+
all: Record<string, unknown>;
|
|
559
|
+
}
|
|
560
|
+
interface FormBuilderHandle {
|
|
561
|
+
/** The current document, fully resolved (same shape as the "View JSON" export). */
|
|
562
|
+
getDocument(): FormDocument;
|
|
563
|
+
/** Replaces the current document — e.g. a form fetched from your own backend. Routes through the same migration path as opening a saved template, so older/looser JSON shapes are tolerated. */
|
|
564
|
+
loadDocument(doc: FormDocument): void;
|
|
565
|
+
/** Convenience for `JSON.stringify(getDocument())`. */
|
|
566
|
+
exportJson(): string;
|
|
567
|
+
}
|
|
568
|
+
interface FormBuilderFeatures {
|
|
569
|
+
/** Editable form title input in the Toolbar. Default true. */
|
|
570
|
+
naming?: boolean;
|
|
571
|
+
/** Templates library (browse/open/delete) + "Save" button. Default true. */
|
|
572
|
+
templates?: boolean;
|
|
573
|
+
/** "New Form" reset button. Default true. */
|
|
574
|
+
newForm?: boolean;
|
|
575
|
+
/** Autosave the draft to `storage`. The initial draft load always happens; this only gates the write path. Default true. */
|
|
576
|
+
autosave?: boolean;
|
|
577
|
+
/** "View JSON" button + modal. Default true. */
|
|
578
|
+
jsonView?: boolean;
|
|
579
|
+
/** Build/Preview mode tabs. When false, the builder stays in Build mode and the tabs are hidden. Default true. */
|
|
580
|
+
previewMode?: boolean;
|
|
581
|
+
/** Language switcher in the Toolbar. Default true. */
|
|
582
|
+
languageSwitcher?: boolean;
|
|
583
|
+
/** Global "Design" tab (colors/spacing) in the sidebar. Replaces the old `themeEditable` prop. Default false. */
|
|
584
|
+
design?: boolean;
|
|
585
|
+
/** Per-field styling controls: paragraph heading/font/color, button color. Independent of `design`. Default true. */
|
|
586
|
+
blockStyling?: boolean;
|
|
587
|
+
/** Which content blocks (paragraph/image/button) can be added from the palette. `true` = all, `false` = none, or an allowlist array. Default true. */
|
|
588
|
+
contentBlocks?: boolean | ContentBlockType[];
|
|
589
|
+
/** Which form field types can be added from the palette. `true` = all, `false` = none, or an allowlist array. Default true. */
|
|
590
|
+
fieldTypes?: boolean | InputFieldType[];
|
|
591
|
+
/** Add/duplicate/move/delete section controls + section background picker. Default true. */
|
|
592
|
+
sections?: boolean;
|
|
593
|
+
/** Drag-to-reorder fields within a section. Default true. */
|
|
594
|
+
dragReorder?: boolean;
|
|
595
|
+
}
|
|
514
596
|
interface FormBuilderProps {
|
|
515
597
|
theme?: Partial<Theme>;
|
|
516
598
|
language?: string;
|
|
517
599
|
languages?: LanguageOption[];
|
|
518
600
|
strings?: Record<string, Partial<StringsShape>>;
|
|
519
601
|
chrome?: Record<string, Partial<ChromeShape>>;
|
|
520
|
-
|
|
602
|
+
/** Independently toggle UI surfaces on/off — full-featured by default. See `FormBuilderFeatures`. */
|
|
603
|
+
features?: FormBuilderFeatures;
|
|
521
604
|
storage?: StorageAdapter;
|
|
605
|
+
onSubmit?: (payload: SubmitPayload) => void;
|
|
606
|
+
/** Seeds the builder with this document on mount instead of the autosaved draft — e.g. a template fetched from your own backend. */
|
|
607
|
+
initialDocument?: FormDocument;
|
|
522
608
|
}
|
|
523
609
|
|
|
524
|
-
declare
|
|
610
|
+
declare const FormBuilder: react.ForwardRefExoticComponent<FormBuilderProps & react.RefAttributes<FormBuilderHandle>>;
|
|
525
611
|
|
|
526
612
|
/**
|
|
527
613
|
* Default StorageAdapter, backed by window.localStorage. Availability is
|
|
528
614
|
* checked inside each method (not once at module load) so the same module
|
|
529
615
|
* behaves correctly whether it runs during SSR (no window) or later on the
|
|
530
616
|
* client, within the same process.
|
|
617
|
+
*
|
|
618
|
+
* Values are compressed before writing (drafts/templates are JSON with a lot
|
|
619
|
+
* of repeated keys, which compresses well) to reduce how much of the quota
|
|
620
|
+
* they use. On read, a decompressed result is only trusted if it's valid
|
|
621
|
+
* JSON — anything else falls back to the raw stored string, so drafts
|
|
622
|
+
* written before compression was added keep loading correctly.
|
|
531
623
|
*/
|
|
532
624
|
declare const localStorageAdapter: StorageAdapter;
|
|
533
625
|
|
|
534
|
-
|
|
626
|
+
declare const DEFAULT_THEME: Theme;
|
|
627
|
+
|
|
628
|
+
/** A ready-made dark palette — pass as the `theme` prop for a dark-mode `<FormBuilder />`. */
|
|
629
|
+
declare const DARK_THEME: Theme;
|
|
630
|
+
|
|
631
|
+
export { type CheckboxField, type CheckboxGroupField, type ChromeShape, type ContentBlockType, DARK_THEME, DEFAULT_THEME, type DocumentFields, type FieldPatch, type FieldType, FormBuilder, type FormBuilderFeatures, type FormBuilderHandle, type FormBuilderProps, type FormDocument, type FormField, type ImageField, type InputField, type InputFieldType, type LanguageOption, type LocalizedString, type Option, type ParagraphField, type RadioField, type SavedFormMeta, type Section, type SelectField, type StorageAdapter, type StringsShape, type SubmitPayload, type SubmitStyle, type TextareaField, type Theme, type ThemeLayout, type ThemeOverrides, type ToggleField, FormBuilder as default, localStorageAdapter };
|
package/dist/index.d.ts
CHANGED
|
@@ -28,13 +28,15 @@ declare const ICON_LIBRARY: {
|
|
|
28
28
|
};
|
|
29
29
|
type IconKey = keyof typeof ICON_LIBRARY;
|
|
30
30
|
|
|
31
|
-
type FieldType = "paragraph" | "image" | "input" | "textarea" | "select" | "radio" | "checkboxGroup" | "checkbox" | "toggle";
|
|
31
|
+
type FieldType = "paragraph" | "image" | "button" | "input" | "textarea" | "select" | "radio" | "checkboxGroup" | "checkbox" | "toggle";
|
|
32
32
|
|
|
33
33
|
declare const CHROME: {
|
|
34
34
|
en: {
|
|
35
35
|
contentBlocks: string;
|
|
36
36
|
formFields: string;
|
|
37
37
|
addingTo: string;
|
|
38
|
+
paletteTabBlocks: string;
|
|
39
|
+
paletteTabDesign: string;
|
|
38
40
|
properties: string;
|
|
39
41
|
selectFieldHint: string;
|
|
40
42
|
label: string;
|
|
@@ -80,14 +82,14 @@ declare const CHROME: {
|
|
|
80
82
|
build: string;
|
|
81
83
|
preview: string;
|
|
82
84
|
newForm: string;
|
|
83
|
-
|
|
85
|
+
templates: string;
|
|
84
86
|
save: string;
|
|
85
87
|
viewJson: string;
|
|
86
88
|
saving: string;
|
|
87
89
|
saved: string;
|
|
88
90
|
saveFailed: string;
|
|
89
91
|
startNewForm: string;
|
|
90
|
-
|
|
92
|
+
openTemplatesTitle: string;
|
|
91
93
|
saveToLibraryTitle: string;
|
|
92
94
|
sectionTitlePlaceholder: (n: number) => string;
|
|
93
95
|
noFieldsInSection: string;
|
|
@@ -101,22 +103,17 @@ declare const CHROME: {
|
|
|
101
103
|
formJson: string;
|
|
102
104
|
copy: string;
|
|
103
105
|
copied: string;
|
|
104
|
-
|
|
106
|
+
noTemplates: string;
|
|
105
107
|
updated: string;
|
|
106
108
|
open: string;
|
|
107
109
|
saveForm: string;
|
|
108
110
|
formName: string;
|
|
109
111
|
saveToLibrary: string;
|
|
110
112
|
loadingDraft: string;
|
|
113
|
+
templatesLimitReached: string;
|
|
111
114
|
current: string;
|
|
112
115
|
customColor: string;
|
|
113
116
|
fieldsCount: (n: number) => string;
|
|
114
|
-
formSettings: string;
|
|
115
|
-
submitLabel: string;
|
|
116
|
-
submitMode: string;
|
|
117
|
-
combined: string;
|
|
118
|
-
perSection: string;
|
|
119
|
-
settings: string;
|
|
120
117
|
fieldTypeInput: string;
|
|
121
118
|
fieldTypeTextarea: string;
|
|
122
119
|
fieldTypeSelect: string;
|
|
@@ -126,6 +123,7 @@ declare const CHROME: {
|
|
|
126
123
|
fieldTypeToggle: string;
|
|
127
124
|
fieldTypeParagraph: string;
|
|
128
125
|
fieldTypeImage: string;
|
|
126
|
+
fieldTypeButton: string;
|
|
129
127
|
subtypeText: string;
|
|
130
128
|
subtypeEmail: string;
|
|
131
129
|
subtypePhone: string;
|
|
@@ -138,8 +136,17 @@ declare const CHROME: {
|
|
|
138
136
|
shapeBanner: string;
|
|
139
137
|
tagBody: string;
|
|
140
138
|
tagCaption: string;
|
|
141
|
-
|
|
142
|
-
|
|
139
|
+
buttonText: string;
|
|
140
|
+
buttonActionTitle: string;
|
|
141
|
+
buttonAction: string;
|
|
142
|
+
actionLink: string;
|
|
143
|
+
actionSubmit: string;
|
|
144
|
+
openIn: string;
|
|
145
|
+
sameTab: string;
|
|
146
|
+
newTab: string;
|
|
147
|
+
submitScope: string;
|
|
148
|
+
thisSection: string;
|
|
149
|
+
wholeForm: string;
|
|
143
150
|
buttonSize: string;
|
|
144
151
|
theme: string;
|
|
145
152
|
primaryColor: string;
|
|
@@ -164,6 +171,8 @@ declare const CHROME: {
|
|
|
164
171
|
contentBlocks: string;
|
|
165
172
|
formFields: string;
|
|
166
173
|
addingTo: string;
|
|
174
|
+
paletteTabBlocks: string;
|
|
175
|
+
paletteTabDesign: string;
|
|
167
176
|
properties: string;
|
|
168
177
|
selectFieldHint: string;
|
|
169
178
|
label: string;
|
|
@@ -209,14 +218,14 @@ declare const CHROME: {
|
|
|
209
218
|
build: string;
|
|
210
219
|
preview: string;
|
|
211
220
|
newForm: string;
|
|
212
|
-
|
|
221
|
+
templates: string;
|
|
213
222
|
save: string;
|
|
214
223
|
viewJson: string;
|
|
215
224
|
saving: string;
|
|
216
225
|
saved: string;
|
|
217
226
|
saveFailed: string;
|
|
218
227
|
startNewForm: string;
|
|
219
|
-
|
|
228
|
+
openTemplatesTitle: string;
|
|
220
229
|
saveToLibraryTitle: string;
|
|
221
230
|
sectionTitlePlaceholder: (n: number) => string;
|
|
222
231
|
noFieldsInSection: string;
|
|
@@ -230,22 +239,17 @@ declare const CHROME: {
|
|
|
230
239
|
formJson: string;
|
|
231
240
|
copy: string;
|
|
232
241
|
copied: string;
|
|
233
|
-
|
|
242
|
+
noTemplates: string;
|
|
234
243
|
updated: string;
|
|
235
244
|
open: string;
|
|
236
245
|
saveForm: string;
|
|
237
246
|
formName: string;
|
|
238
247
|
saveToLibrary: string;
|
|
239
248
|
loadingDraft: string;
|
|
249
|
+
templatesLimitReached: string;
|
|
240
250
|
current: string;
|
|
241
251
|
customColor: string;
|
|
242
252
|
fieldsCount: (n: number) => string;
|
|
243
|
-
formSettings: string;
|
|
244
|
-
submitLabel: string;
|
|
245
|
-
submitMode: string;
|
|
246
|
-
combined: string;
|
|
247
|
-
perSection: string;
|
|
248
|
-
settings: string;
|
|
249
253
|
fieldTypeInput: string;
|
|
250
254
|
fieldTypeTextarea: string;
|
|
251
255
|
fieldTypeSelect: string;
|
|
@@ -255,6 +259,7 @@ declare const CHROME: {
|
|
|
255
259
|
fieldTypeToggle: string;
|
|
256
260
|
fieldTypeParagraph: string;
|
|
257
261
|
fieldTypeImage: string;
|
|
262
|
+
fieldTypeButton: string;
|
|
258
263
|
subtypeText: string;
|
|
259
264
|
subtypeEmail: string;
|
|
260
265
|
subtypePhone: string;
|
|
@@ -267,8 +272,17 @@ declare const CHROME: {
|
|
|
267
272
|
shapeBanner: string;
|
|
268
273
|
tagBody: string;
|
|
269
274
|
tagCaption: string;
|
|
270
|
-
|
|
271
|
-
|
|
275
|
+
buttonText: string;
|
|
276
|
+
buttonActionTitle: string;
|
|
277
|
+
buttonAction: string;
|
|
278
|
+
actionLink: string;
|
|
279
|
+
actionSubmit: string;
|
|
280
|
+
openIn: string;
|
|
281
|
+
sameTab: string;
|
|
282
|
+
newTab: string;
|
|
283
|
+
submitScope: string;
|
|
284
|
+
thisSection: string;
|
|
285
|
+
wholeForm: string;
|
|
272
286
|
buttonSize: string;
|
|
273
287
|
theme: string;
|
|
274
288
|
primaryColor: string;
|
|
@@ -331,6 +345,8 @@ interface LanguageOption {
|
|
|
331
345
|
label: string;
|
|
332
346
|
}
|
|
333
347
|
|
|
348
|
+
type ContentBlockType = "paragraph" | "image" | "button";
|
|
349
|
+
type InputFieldType = "input" | "textarea" | "select" | "radio" | "checkboxGroup" | "checkbox" | "toggle";
|
|
334
350
|
interface LocalizedString {
|
|
335
351
|
en: string;
|
|
336
352
|
[lang: string]: string | undefined;
|
|
@@ -416,7 +432,17 @@ interface ImageField extends BaseField {
|
|
|
416
432
|
link: string;
|
|
417
433
|
shape: "square" | "circle" | "banner";
|
|
418
434
|
}
|
|
419
|
-
|
|
435
|
+
interface ButtonField extends BaseField {
|
|
436
|
+
type: "button";
|
|
437
|
+
action: "link" | "submit";
|
|
438
|
+
buttonStyle: SubmitStyle;
|
|
439
|
+
/** Used when `action === "link"`. */
|
|
440
|
+
href: string;
|
|
441
|
+
target: "_self" | "_blank";
|
|
442
|
+
/** Used when `action === "submit"`. */
|
|
443
|
+
submitScope: "section" | "form";
|
|
444
|
+
}
|
|
445
|
+
type FormField = InputField | TextareaField | SelectField | RadioField | CheckboxGroupField | CheckboxField | ToggleField | ParagraphField | ImageField | ButtonField;
|
|
420
446
|
/**
|
|
421
447
|
* Flat, fully-optional patch type for updateField/updateOption call sites.
|
|
422
448
|
* A strict `Partial<FormField>` doesn't typecheck for cross-type shallow
|
|
@@ -450,6 +476,11 @@ interface FieldPatch {
|
|
|
450
476
|
alt?: LocalizedString;
|
|
451
477
|
link?: string;
|
|
452
478
|
shape?: ImageField["shape"];
|
|
479
|
+
action?: ButtonField["action"];
|
|
480
|
+
buttonStyle?: SubmitStyle;
|
|
481
|
+
href?: string;
|
|
482
|
+
target?: ButtonField["target"];
|
|
483
|
+
submitScope?: ButtonField["submitScope"];
|
|
453
484
|
}
|
|
454
485
|
interface SubmitStyle {
|
|
455
486
|
color: string;
|
|
@@ -460,20 +491,18 @@ interface Section {
|
|
|
460
491
|
title: LocalizedString;
|
|
461
492
|
background: string;
|
|
462
493
|
collapsed: boolean;
|
|
463
|
-
submitStyle: SubmitStyle | null;
|
|
464
494
|
fields: FormField[];
|
|
465
495
|
}
|
|
466
496
|
interface DocumentFields {
|
|
467
497
|
title: LocalizedString;
|
|
468
|
-
submitLabel: LocalizedString;
|
|
469
|
-
submitMode: "combined" | "perSection";
|
|
470
|
-
submitStyle: SubmitStyle;
|
|
471
498
|
themeOverrides: ThemeOverrides;
|
|
472
499
|
sections: Section[];
|
|
473
500
|
}
|
|
474
501
|
/** Shape used only for the "View JSON" export (stamped with a version). */
|
|
475
502
|
interface FormDocument extends DocumentFields {
|
|
476
|
-
version:
|
|
503
|
+
version: 5;
|
|
504
|
+
/** Fully resolved theme (DEFAULT_THEME merged with `themeOverrides`) — lets a host re-render this document's styling without needing its own copy of the defaults. */
|
|
505
|
+
theme: Theme;
|
|
477
506
|
}
|
|
478
507
|
interface SavedFormMeta {
|
|
479
508
|
id: string;
|
|
@@ -511,24 +540,92 @@ interface StorageAdapter {
|
|
|
511
540
|
set(key: string, value: string): Promise<void>;
|
|
512
541
|
delete(key: string): Promise<void>;
|
|
513
542
|
}
|
|
543
|
+
interface SubmitPayload {
|
|
544
|
+
/** id of the button field that triggered this submission. */
|
|
545
|
+
buttonId: string;
|
|
546
|
+
/** Whether the triggering button's scope was the whole form or just its own section. */
|
|
547
|
+
scope: "form" | "section";
|
|
548
|
+
/** Set when `scope === "section"`. */
|
|
549
|
+
sectionId?: string;
|
|
550
|
+
/** fieldId -> raw value, scoped to whatever was just submitted (the whole form for "combined", one section for "section"). */
|
|
551
|
+
values: Record<string, unknown>;
|
|
552
|
+
/** Section-wise breakdown of the *entire* form, regardless of scope. */
|
|
553
|
+
sections: {
|
|
554
|
+
sectionId: string;
|
|
555
|
+
values: Record<string, unknown>;
|
|
556
|
+
}[];
|
|
557
|
+
/** Flattened fieldId -> raw value across every section, for convenience. */
|
|
558
|
+
all: Record<string, unknown>;
|
|
559
|
+
}
|
|
560
|
+
interface FormBuilderHandle {
|
|
561
|
+
/** The current document, fully resolved (same shape as the "View JSON" export). */
|
|
562
|
+
getDocument(): FormDocument;
|
|
563
|
+
/** Replaces the current document — e.g. a form fetched from your own backend. Routes through the same migration path as opening a saved template, so older/looser JSON shapes are tolerated. */
|
|
564
|
+
loadDocument(doc: FormDocument): void;
|
|
565
|
+
/** Convenience for `JSON.stringify(getDocument())`. */
|
|
566
|
+
exportJson(): string;
|
|
567
|
+
}
|
|
568
|
+
interface FormBuilderFeatures {
|
|
569
|
+
/** Editable form title input in the Toolbar. Default true. */
|
|
570
|
+
naming?: boolean;
|
|
571
|
+
/** Templates library (browse/open/delete) + "Save" button. Default true. */
|
|
572
|
+
templates?: boolean;
|
|
573
|
+
/** "New Form" reset button. Default true. */
|
|
574
|
+
newForm?: boolean;
|
|
575
|
+
/** Autosave the draft to `storage`. The initial draft load always happens; this only gates the write path. Default true. */
|
|
576
|
+
autosave?: boolean;
|
|
577
|
+
/** "View JSON" button + modal. Default true. */
|
|
578
|
+
jsonView?: boolean;
|
|
579
|
+
/** Build/Preview mode tabs. When false, the builder stays in Build mode and the tabs are hidden. Default true. */
|
|
580
|
+
previewMode?: boolean;
|
|
581
|
+
/** Language switcher in the Toolbar. Default true. */
|
|
582
|
+
languageSwitcher?: boolean;
|
|
583
|
+
/** Global "Design" tab (colors/spacing) in the sidebar. Replaces the old `themeEditable` prop. Default false. */
|
|
584
|
+
design?: boolean;
|
|
585
|
+
/** Per-field styling controls: paragraph heading/font/color, button color. Independent of `design`. Default true. */
|
|
586
|
+
blockStyling?: boolean;
|
|
587
|
+
/** Which content blocks (paragraph/image/button) can be added from the palette. `true` = all, `false` = none, or an allowlist array. Default true. */
|
|
588
|
+
contentBlocks?: boolean | ContentBlockType[];
|
|
589
|
+
/** Which form field types can be added from the palette. `true` = all, `false` = none, or an allowlist array. Default true. */
|
|
590
|
+
fieldTypes?: boolean | InputFieldType[];
|
|
591
|
+
/** Add/duplicate/move/delete section controls + section background picker. Default true. */
|
|
592
|
+
sections?: boolean;
|
|
593
|
+
/** Drag-to-reorder fields within a section. Default true. */
|
|
594
|
+
dragReorder?: boolean;
|
|
595
|
+
}
|
|
514
596
|
interface FormBuilderProps {
|
|
515
597
|
theme?: Partial<Theme>;
|
|
516
598
|
language?: string;
|
|
517
599
|
languages?: LanguageOption[];
|
|
518
600
|
strings?: Record<string, Partial<StringsShape>>;
|
|
519
601
|
chrome?: Record<string, Partial<ChromeShape>>;
|
|
520
|
-
|
|
602
|
+
/** Independently toggle UI surfaces on/off — full-featured by default. See `FormBuilderFeatures`. */
|
|
603
|
+
features?: FormBuilderFeatures;
|
|
521
604
|
storage?: StorageAdapter;
|
|
605
|
+
onSubmit?: (payload: SubmitPayload) => void;
|
|
606
|
+
/** Seeds the builder with this document on mount instead of the autosaved draft — e.g. a template fetched from your own backend. */
|
|
607
|
+
initialDocument?: FormDocument;
|
|
522
608
|
}
|
|
523
609
|
|
|
524
|
-
declare
|
|
610
|
+
declare const FormBuilder: react.ForwardRefExoticComponent<FormBuilderProps & react.RefAttributes<FormBuilderHandle>>;
|
|
525
611
|
|
|
526
612
|
/**
|
|
527
613
|
* Default StorageAdapter, backed by window.localStorage. Availability is
|
|
528
614
|
* checked inside each method (not once at module load) so the same module
|
|
529
615
|
* behaves correctly whether it runs during SSR (no window) or later on the
|
|
530
616
|
* client, within the same process.
|
|
617
|
+
*
|
|
618
|
+
* Values are compressed before writing (drafts/templates are JSON with a lot
|
|
619
|
+
* of repeated keys, which compresses well) to reduce how much of the quota
|
|
620
|
+
* they use. On read, a decompressed result is only trusted if it's valid
|
|
621
|
+
* JSON — anything else falls back to the raw stored string, so drafts
|
|
622
|
+
* written before compression was added keep loading correctly.
|
|
531
623
|
*/
|
|
532
624
|
declare const localStorageAdapter: StorageAdapter;
|
|
533
625
|
|
|
534
|
-
|
|
626
|
+
declare const DEFAULT_THEME: Theme;
|
|
627
|
+
|
|
628
|
+
/** A ready-made dark palette — pass as the `theme` prop for a dark-mode `<FormBuilder />`. */
|
|
629
|
+
declare const DARK_THEME: Theme;
|
|
630
|
+
|
|
631
|
+
export { type CheckboxField, type CheckboxGroupField, type ChromeShape, type ContentBlockType, DARK_THEME, DEFAULT_THEME, type DocumentFields, type FieldPatch, type FieldType, FormBuilder, type FormBuilderFeatures, type FormBuilderHandle, type FormBuilderProps, type FormDocument, type FormField, type ImageField, type InputField, type InputFieldType, type LanguageOption, type LocalizedString, type Option, type ParagraphField, type RadioField, type SavedFormMeta, type Section, type SelectField, type StorageAdapter, type StringsShape, type SubmitPayload, type SubmitStyle, type TextareaField, type Theme, type ThemeLayout, type ThemeOverrides, type ToggleField, FormBuilder as default, localStorageAdapter };
|