form-page-builder 0.1.0 → 1.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 +100 -8
- package/dist/index.cjs +846 -742
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +92 -31
- package/dist/index.d.ts +92 -31
- package/dist/index.js +846 -741
- package/dist/index.js.map +1 -1
- package/package.json +4 -3
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;
|
|
@@ -416,7 +430,17 @@ interface ImageField extends BaseField {
|
|
|
416
430
|
link: string;
|
|
417
431
|
shape: "square" | "circle" | "banner";
|
|
418
432
|
}
|
|
419
|
-
|
|
433
|
+
interface ButtonField extends BaseField {
|
|
434
|
+
type: "button";
|
|
435
|
+
action: "link" | "submit";
|
|
436
|
+
buttonStyle: SubmitStyle;
|
|
437
|
+
/** Used when `action === "link"`. */
|
|
438
|
+
href: string;
|
|
439
|
+
target: "_self" | "_blank";
|
|
440
|
+
/** Used when `action === "submit"`. */
|
|
441
|
+
submitScope: "section" | "form";
|
|
442
|
+
}
|
|
443
|
+
type FormField = InputField | TextareaField | SelectField | RadioField | CheckboxGroupField | CheckboxField | ToggleField | ParagraphField | ImageField | ButtonField;
|
|
420
444
|
/**
|
|
421
445
|
* Flat, fully-optional patch type for updateField/updateOption call sites.
|
|
422
446
|
* A strict `Partial<FormField>` doesn't typecheck for cross-type shallow
|
|
@@ -450,6 +474,11 @@ interface FieldPatch {
|
|
|
450
474
|
alt?: LocalizedString;
|
|
451
475
|
link?: string;
|
|
452
476
|
shape?: ImageField["shape"];
|
|
477
|
+
action?: ButtonField["action"];
|
|
478
|
+
buttonStyle?: SubmitStyle;
|
|
479
|
+
href?: string;
|
|
480
|
+
target?: ButtonField["target"];
|
|
481
|
+
submitScope?: ButtonField["submitScope"];
|
|
453
482
|
}
|
|
454
483
|
interface SubmitStyle {
|
|
455
484
|
color: string;
|
|
@@ -460,20 +489,18 @@ interface Section {
|
|
|
460
489
|
title: LocalizedString;
|
|
461
490
|
background: string;
|
|
462
491
|
collapsed: boolean;
|
|
463
|
-
submitStyle: SubmitStyle | null;
|
|
464
492
|
fields: FormField[];
|
|
465
493
|
}
|
|
466
494
|
interface DocumentFields {
|
|
467
495
|
title: LocalizedString;
|
|
468
|
-
submitLabel: LocalizedString;
|
|
469
|
-
submitMode: "combined" | "perSection";
|
|
470
|
-
submitStyle: SubmitStyle;
|
|
471
496
|
themeOverrides: ThemeOverrides;
|
|
472
497
|
sections: Section[];
|
|
473
498
|
}
|
|
474
499
|
/** Shape used only for the "View JSON" export (stamped with a version). */
|
|
475
500
|
interface FormDocument extends DocumentFields {
|
|
476
|
-
version:
|
|
501
|
+
version: 5;
|
|
502
|
+
/** 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. */
|
|
503
|
+
theme: Theme;
|
|
477
504
|
}
|
|
478
505
|
interface SavedFormMeta {
|
|
479
506
|
id: string;
|
|
@@ -511,6 +538,31 @@ interface StorageAdapter {
|
|
|
511
538
|
set(key: string, value: string): Promise<void>;
|
|
512
539
|
delete(key: string): Promise<void>;
|
|
513
540
|
}
|
|
541
|
+
interface SubmitPayload {
|
|
542
|
+
/** id of the button field that triggered this submission. */
|
|
543
|
+
buttonId: string;
|
|
544
|
+
/** Whether the triggering button's scope was the whole form or just its own section. */
|
|
545
|
+
scope: "form" | "section";
|
|
546
|
+
/** Set when `scope === "section"`. */
|
|
547
|
+
sectionId?: string;
|
|
548
|
+
/** fieldId -> raw value, scoped to whatever was just submitted (the whole form for "combined", one section for "section"). */
|
|
549
|
+
values: Record<string, unknown>;
|
|
550
|
+
/** Section-wise breakdown of the *entire* form, regardless of scope. */
|
|
551
|
+
sections: {
|
|
552
|
+
sectionId: string;
|
|
553
|
+
values: Record<string, unknown>;
|
|
554
|
+
}[];
|
|
555
|
+
/** Flattened fieldId -> raw value across every section, for convenience. */
|
|
556
|
+
all: Record<string, unknown>;
|
|
557
|
+
}
|
|
558
|
+
interface FormBuilderHandle {
|
|
559
|
+
/** The current document, fully resolved (same shape as the "View JSON" export). */
|
|
560
|
+
getDocument(): FormDocument;
|
|
561
|
+
/** 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. */
|
|
562
|
+
loadDocument(doc: FormDocument): void;
|
|
563
|
+
/** Convenience for `JSON.stringify(getDocument())`. */
|
|
564
|
+
exportJson(): string;
|
|
565
|
+
}
|
|
514
566
|
interface FormBuilderProps {
|
|
515
567
|
theme?: Partial<Theme>;
|
|
516
568
|
language?: string;
|
|
@@ -519,16 +571,25 @@ interface FormBuilderProps {
|
|
|
519
571
|
chrome?: Record<string, Partial<ChromeShape>>;
|
|
520
572
|
themeEditable?: boolean;
|
|
521
573
|
storage?: StorageAdapter;
|
|
574
|
+
onSubmit?: (payload: SubmitPayload) => void;
|
|
575
|
+
/** Seeds the builder with this document on mount instead of the autosaved draft — e.g. a template fetched from your own backend. */
|
|
576
|
+
initialDocument?: FormDocument;
|
|
522
577
|
}
|
|
523
578
|
|
|
524
|
-
declare
|
|
579
|
+
declare const FormBuilder: react.ForwardRefExoticComponent<FormBuilderProps & react.RefAttributes<FormBuilderHandle>>;
|
|
525
580
|
|
|
526
581
|
/**
|
|
527
582
|
* Default StorageAdapter, backed by window.localStorage. Availability is
|
|
528
583
|
* checked inside each method (not once at module load) so the same module
|
|
529
584
|
* behaves correctly whether it runs during SSR (no window) or later on the
|
|
530
585
|
* client, within the same process.
|
|
586
|
+
*
|
|
587
|
+
* Values are compressed before writing (drafts/templates are JSON with a lot
|
|
588
|
+
* of repeated keys, which compresses well) to reduce how much of the quota
|
|
589
|
+
* they use. On read, a decompressed result is only trusted if it's valid
|
|
590
|
+
* JSON — anything else falls back to the raw stored string, so drafts
|
|
591
|
+
* written before compression was added keep loading correctly.
|
|
531
592
|
*/
|
|
532
593
|
declare const localStorageAdapter: StorageAdapter;
|
|
533
594
|
|
|
534
|
-
export { type CheckboxField, type CheckboxGroupField, type ChromeShape, type DocumentFields, type FieldPatch, type FieldType, FormBuilder, type FormBuilderProps, type FormDocument, type FormField, type ImageField, type InputField, type LanguageOption, type LocalizedString, type Option, type ParagraphField, type RadioField, type SavedFormMeta, type Section, type SelectField, type StorageAdapter, type StringsShape, type SubmitStyle, type TextareaField, type Theme, type ThemeLayout, type ThemeOverrides, type ToggleField, FormBuilder as default, localStorageAdapter };
|
|
595
|
+
export { type CheckboxField, type CheckboxGroupField, type ChromeShape, type DocumentFields, type FieldPatch, type FieldType, FormBuilder, type FormBuilderHandle, type FormBuilderProps, type FormDocument, type FormField, type ImageField, type InputField, 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;
|
|
@@ -416,7 +430,17 @@ interface ImageField extends BaseField {
|
|
|
416
430
|
link: string;
|
|
417
431
|
shape: "square" | "circle" | "banner";
|
|
418
432
|
}
|
|
419
|
-
|
|
433
|
+
interface ButtonField extends BaseField {
|
|
434
|
+
type: "button";
|
|
435
|
+
action: "link" | "submit";
|
|
436
|
+
buttonStyle: SubmitStyle;
|
|
437
|
+
/** Used when `action === "link"`. */
|
|
438
|
+
href: string;
|
|
439
|
+
target: "_self" | "_blank";
|
|
440
|
+
/** Used when `action === "submit"`. */
|
|
441
|
+
submitScope: "section" | "form";
|
|
442
|
+
}
|
|
443
|
+
type FormField = InputField | TextareaField | SelectField | RadioField | CheckboxGroupField | CheckboxField | ToggleField | ParagraphField | ImageField | ButtonField;
|
|
420
444
|
/**
|
|
421
445
|
* Flat, fully-optional patch type for updateField/updateOption call sites.
|
|
422
446
|
* A strict `Partial<FormField>` doesn't typecheck for cross-type shallow
|
|
@@ -450,6 +474,11 @@ interface FieldPatch {
|
|
|
450
474
|
alt?: LocalizedString;
|
|
451
475
|
link?: string;
|
|
452
476
|
shape?: ImageField["shape"];
|
|
477
|
+
action?: ButtonField["action"];
|
|
478
|
+
buttonStyle?: SubmitStyle;
|
|
479
|
+
href?: string;
|
|
480
|
+
target?: ButtonField["target"];
|
|
481
|
+
submitScope?: ButtonField["submitScope"];
|
|
453
482
|
}
|
|
454
483
|
interface SubmitStyle {
|
|
455
484
|
color: string;
|
|
@@ -460,20 +489,18 @@ interface Section {
|
|
|
460
489
|
title: LocalizedString;
|
|
461
490
|
background: string;
|
|
462
491
|
collapsed: boolean;
|
|
463
|
-
submitStyle: SubmitStyle | null;
|
|
464
492
|
fields: FormField[];
|
|
465
493
|
}
|
|
466
494
|
interface DocumentFields {
|
|
467
495
|
title: LocalizedString;
|
|
468
|
-
submitLabel: LocalizedString;
|
|
469
|
-
submitMode: "combined" | "perSection";
|
|
470
|
-
submitStyle: SubmitStyle;
|
|
471
496
|
themeOverrides: ThemeOverrides;
|
|
472
497
|
sections: Section[];
|
|
473
498
|
}
|
|
474
499
|
/** Shape used only for the "View JSON" export (stamped with a version). */
|
|
475
500
|
interface FormDocument extends DocumentFields {
|
|
476
|
-
version:
|
|
501
|
+
version: 5;
|
|
502
|
+
/** 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. */
|
|
503
|
+
theme: Theme;
|
|
477
504
|
}
|
|
478
505
|
interface SavedFormMeta {
|
|
479
506
|
id: string;
|
|
@@ -511,6 +538,31 @@ interface StorageAdapter {
|
|
|
511
538
|
set(key: string, value: string): Promise<void>;
|
|
512
539
|
delete(key: string): Promise<void>;
|
|
513
540
|
}
|
|
541
|
+
interface SubmitPayload {
|
|
542
|
+
/** id of the button field that triggered this submission. */
|
|
543
|
+
buttonId: string;
|
|
544
|
+
/** Whether the triggering button's scope was the whole form or just its own section. */
|
|
545
|
+
scope: "form" | "section";
|
|
546
|
+
/** Set when `scope === "section"`. */
|
|
547
|
+
sectionId?: string;
|
|
548
|
+
/** fieldId -> raw value, scoped to whatever was just submitted (the whole form for "combined", one section for "section"). */
|
|
549
|
+
values: Record<string, unknown>;
|
|
550
|
+
/** Section-wise breakdown of the *entire* form, regardless of scope. */
|
|
551
|
+
sections: {
|
|
552
|
+
sectionId: string;
|
|
553
|
+
values: Record<string, unknown>;
|
|
554
|
+
}[];
|
|
555
|
+
/** Flattened fieldId -> raw value across every section, for convenience. */
|
|
556
|
+
all: Record<string, unknown>;
|
|
557
|
+
}
|
|
558
|
+
interface FormBuilderHandle {
|
|
559
|
+
/** The current document, fully resolved (same shape as the "View JSON" export). */
|
|
560
|
+
getDocument(): FormDocument;
|
|
561
|
+
/** 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. */
|
|
562
|
+
loadDocument(doc: FormDocument): void;
|
|
563
|
+
/** Convenience for `JSON.stringify(getDocument())`. */
|
|
564
|
+
exportJson(): string;
|
|
565
|
+
}
|
|
514
566
|
interface FormBuilderProps {
|
|
515
567
|
theme?: Partial<Theme>;
|
|
516
568
|
language?: string;
|
|
@@ -519,16 +571,25 @@ interface FormBuilderProps {
|
|
|
519
571
|
chrome?: Record<string, Partial<ChromeShape>>;
|
|
520
572
|
themeEditable?: boolean;
|
|
521
573
|
storage?: StorageAdapter;
|
|
574
|
+
onSubmit?: (payload: SubmitPayload) => void;
|
|
575
|
+
/** Seeds the builder with this document on mount instead of the autosaved draft — e.g. a template fetched from your own backend. */
|
|
576
|
+
initialDocument?: FormDocument;
|
|
522
577
|
}
|
|
523
578
|
|
|
524
|
-
declare
|
|
579
|
+
declare const FormBuilder: react.ForwardRefExoticComponent<FormBuilderProps & react.RefAttributes<FormBuilderHandle>>;
|
|
525
580
|
|
|
526
581
|
/**
|
|
527
582
|
* Default StorageAdapter, backed by window.localStorage. Availability is
|
|
528
583
|
* checked inside each method (not once at module load) so the same module
|
|
529
584
|
* behaves correctly whether it runs during SSR (no window) or later on the
|
|
530
585
|
* client, within the same process.
|
|
586
|
+
*
|
|
587
|
+
* Values are compressed before writing (drafts/templates are JSON with a lot
|
|
588
|
+
* of repeated keys, which compresses well) to reduce how much of the quota
|
|
589
|
+
* they use. On read, a decompressed result is only trusted if it's valid
|
|
590
|
+
* JSON — anything else falls back to the raw stored string, so drafts
|
|
591
|
+
* written before compression was added keep loading correctly.
|
|
531
592
|
*/
|
|
532
593
|
declare const localStorageAdapter: StorageAdapter;
|
|
533
594
|
|
|
534
|
-
export { type CheckboxField, type CheckboxGroupField, type ChromeShape, type DocumentFields, type FieldPatch, type FieldType, FormBuilder, type FormBuilderProps, type FormDocument, type FormField, type ImageField, type InputField, type LanguageOption, type LocalizedString, type Option, type ParagraphField, type RadioField, type SavedFormMeta, type Section, type SelectField, type StorageAdapter, type StringsShape, type SubmitStyle, type TextareaField, type Theme, type ThemeLayout, type ThemeOverrides, type ToggleField, FormBuilder as default, localStorageAdapter };
|
|
595
|
+
export { type CheckboxField, type CheckboxGroupField, type ChromeShape, type DocumentFields, type FieldPatch, type FieldType, FormBuilder, type FormBuilderHandle, type FormBuilderProps, type FormDocument, type FormField, type ImageField, type InputField, 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 };
|