form-page-builder 2.0.0 → 2.2.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/README.md +53 -16
- package/dist/index.cjs +561 -193
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +94 -16
- package/dist/index.d.ts +94 -16
- package/dist/index.js +568 -207
- package/dist/index.js.map +1 -1
- package/package.json +12 -2
package/dist/index.d.cts
CHANGED
|
@@ -103,16 +103,33 @@ declare const CHROME: {
|
|
|
103
103
|
formJson: string;
|
|
104
104
|
copy: string;
|
|
105
105
|
copied: string;
|
|
106
|
+
copyTemplate: string;
|
|
107
|
+
pasteTemplate: string;
|
|
108
|
+
copyTemplateTitle: string;
|
|
109
|
+
pasteTemplateTitle: string;
|
|
110
|
+
pasteTemplateConfirm: string;
|
|
106
111
|
noTemplates: string;
|
|
112
|
+
noTemplatesReadonly: string;
|
|
107
113
|
updated: string;
|
|
108
114
|
open: string;
|
|
115
|
+
applyTemplate: string;
|
|
109
116
|
saveForm: string;
|
|
110
117
|
formName: string;
|
|
111
118
|
saveToLibrary: string;
|
|
112
119
|
loadingDraft: string;
|
|
113
|
-
templatesLimitReached: string;
|
|
120
|
+
templatesLimitReached: (max: number) => string;
|
|
121
|
+
templatesLimitTitle: string;
|
|
122
|
+
confirm: string;
|
|
123
|
+
cancel: string;
|
|
124
|
+
dismiss: string;
|
|
125
|
+
confirmReplace: string;
|
|
114
126
|
current: string;
|
|
115
127
|
customColor: string;
|
|
128
|
+
templateLabel: (name: string) => string;
|
|
129
|
+
templateEdited: string;
|
|
130
|
+
templateLoading: string;
|
|
131
|
+
templateLoadFailed: string;
|
|
132
|
+
templateSaveFailed: string;
|
|
116
133
|
fieldsCount: (n: number) => string;
|
|
117
134
|
fieldTypeInput: string;
|
|
118
135
|
fieldTypeTextarea: string;
|
|
@@ -239,16 +256,33 @@ declare const CHROME: {
|
|
|
239
256
|
formJson: string;
|
|
240
257
|
copy: string;
|
|
241
258
|
copied: string;
|
|
259
|
+
copyTemplate: string;
|
|
260
|
+
pasteTemplate: string;
|
|
261
|
+
copyTemplateTitle: string;
|
|
262
|
+
pasteTemplateTitle: string;
|
|
263
|
+
pasteTemplateConfirm: string;
|
|
242
264
|
noTemplates: string;
|
|
265
|
+
noTemplatesReadonly: string;
|
|
243
266
|
updated: string;
|
|
244
267
|
open: string;
|
|
268
|
+
applyTemplate: string;
|
|
245
269
|
saveForm: string;
|
|
246
270
|
formName: string;
|
|
247
271
|
saveToLibrary: string;
|
|
248
272
|
loadingDraft: string;
|
|
249
|
-
templatesLimitReached: string;
|
|
273
|
+
templatesLimitReached: (max: number) => string;
|
|
274
|
+
templatesLimitTitle: string;
|
|
275
|
+
confirm: string;
|
|
276
|
+
cancel: string;
|
|
277
|
+
dismiss: string;
|
|
278
|
+
confirmReplace: string;
|
|
250
279
|
current: string;
|
|
251
280
|
customColor: string;
|
|
281
|
+
templateLabel: (name: string) => string;
|
|
282
|
+
templateEdited: string;
|
|
283
|
+
templateLoading: string;
|
|
284
|
+
templateLoadFailed: string;
|
|
285
|
+
templateSaveFailed: string;
|
|
252
286
|
fieldsCount: (n: number) => string;
|
|
253
287
|
fieldTypeInput: string;
|
|
254
288
|
fieldTypeTextarea: string;
|
|
@@ -564,12 +598,37 @@ interface FormBuilderHandle {
|
|
|
564
598
|
loadDocument(doc: FormDocument): void;
|
|
565
599
|
/** Convenience for `JSON.stringify(getDocument())`. */
|
|
566
600
|
exportJson(): string;
|
|
601
|
+
/** The current document as a portable `FormTemplate` — pass to another builder's `loadTemplate()` or persist it. */
|
|
602
|
+
getTemplate(): FormTemplate;
|
|
603
|
+
/** Loads a `FormTemplate` (or its JSON, or bare document JSON); `false` if it can't be parsed. */
|
|
604
|
+
loadTemplate(input: FormTemplate | string): boolean;
|
|
605
|
+
}
|
|
606
|
+
/** Self-describing `FormDocument` wrapper; the `__fpb` tag marks it as ours. See `serializeTemplate` / `parseTemplate`. */
|
|
607
|
+
interface FormTemplate {
|
|
608
|
+
__fpb: "template";
|
|
609
|
+
v: number;
|
|
610
|
+
document: FormDocument;
|
|
611
|
+
}
|
|
612
|
+
interface TemplateChange {
|
|
613
|
+
/** Affected template's id; `null` when the active template was just deleted. */
|
|
614
|
+
id: string | null;
|
|
615
|
+
title: string;
|
|
616
|
+
/** `new` = created, `saved` = overwritten, `applied` = loaded as the working doc, `deleted`. */
|
|
617
|
+
source: "new" | "saved" | "applied" | "deleted";
|
|
567
618
|
}
|
|
568
619
|
interface FormBuilderFeatures {
|
|
569
620
|
/** Editable form title input in the Toolbar. Default true. */
|
|
570
621
|
naming?: boolean;
|
|
571
|
-
/**
|
|
572
|
-
|
|
622
|
+
/**
|
|
623
|
+
* Templates library. `true` (default) = full CRUD + toolbar "Save"; `false` = hidden.
|
|
624
|
+
* `{ manage: false }` = pick-and-apply only (no save/overwrite/delete). `{ max }` caps the count (default 5).
|
|
625
|
+
*/
|
|
626
|
+
templates?: boolean | {
|
|
627
|
+
manage?: boolean;
|
|
628
|
+
max?: number;
|
|
629
|
+
};
|
|
630
|
+
/** "Copy template" / "Paste template" icons by "View JSON"; paste enables once another instance copies. Default true. */
|
|
631
|
+
templateClipboard?: boolean;
|
|
573
632
|
/** "New Form" reset button. Default true. */
|
|
574
633
|
newForm?: boolean;
|
|
575
634
|
/** Autosave the draft to `storage`. The initial draft load always happens; this only gates the write path. Default true. */
|
|
@@ -588,10 +647,16 @@ interface FormBuilderFeatures {
|
|
|
588
647
|
contentBlocks?: boolean | ContentBlockType[];
|
|
589
648
|
/** Which form field types can be added from the palette. `true` = all, `false` = none, or an allowlist array. Default true. */
|
|
590
649
|
fieldTypes?: boolean | InputFieldType[];
|
|
591
|
-
/** Add/duplicate/move/delete section controls + section
|
|
650
|
+
/** Add/duplicate/move/delete section controls + the "Add section" button. Default true. */
|
|
592
651
|
sections?: boolean;
|
|
652
|
+
/** Per-section background-color picker. Independent of `sections`; unset → follows `sections`, else true. */
|
|
653
|
+
sectionBackground?: boolean;
|
|
593
654
|
/** Drag-to-reorder fields within a section. Default true. */
|
|
594
655
|
dragReorder?: boolean;
|
|
656
|
+
/** Laptop/Tablet/Mobile width switcher above the Preview canvas. Default true. */
|
|
657
|
+
deviceToggle?: boolean;
|
|
658
|
+
/** Caps the number of input-type fields (not content blocks) addable across the whole document. Default undefined (unlimited). */
|
|
659
|
+
maxFields?: number;
|
|
595
660
|
}
|
|
596
661
|
interface FormBuilderProps {
|
|
597
662
|
theme?: Partial<Theme>;
|
|
@@ -605,21 +670,22 @@ interface FormBuilderProps {
|
|
|
605
670
|
onSubmit?: (payload: SubmitPayload) => void;
|
|
606
671
|
/** Seeds the builder with this document on mount instead of the autosaved draft — e.g. a template fetched from your own backend. */
|
|
607
672
|
initialDocument?: FormDocument;
|
|
673
|
+
/** Which mode the widget mounts into. Default "build". Pair with `features.previewMode: false` to lock a consumer to just one mode with no tabs. */
|
|
674
|
+
initialMode?: "build" | "preview";
|
|
675
|
+
/** Fires on mount and on every Build/Preview toggle — lets a host mirror the current mode without its own tab UI. */
|
|
676
|
+
onModeChange?: (mode: "build" | "preview") => void;
|
|
677
|
+
/** Fires on template create/overwrite/apply/delete — for syncing a host's own state/backend. */
|
|
678
|
+
onTemplateChange?: (change: TemplateChange) => void;
|
|
679
|
+
/** localStorage key behind copy/paste (default `"form-page-builder:clipboard"`); instances sharing it can paste to each other. */
|
|
680
|
+
templateClipboardKey?: string;
|
|
608
681
|
}
|
|
609
682
|
|
|
610
683
|
declare const FormBuilder: react.ForwardRefExoticComponent<FormBuilderProps & react.RefAttributes<FormBuilderHandle>>;
|
|
611
684
|
|
|
612
685
|
/**
|
|
613
|
-
* Default StorageAdapter
|
|
614
|
-
*
|
|
615
|
-
*
|
|
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.
|
|
686
|
+
* Default StorageAdapter over window.localStorage. Availability is checked per-call so it survives SSR.
|
|
687
|
+
* Values are compressed on write; on read, a decompressed result is used only if it parses as JSON,
|
|
688
|
+
* else the raw string is returned (so pre-compression drafts still load).
|
|
623
689
|
*/
|
|
624
690
|
declare const localStorageAdapter: StorageAdapter;
|
|
625
691
|
|
|
@@ -628,4 +694,16 @@ declare const DEFAULT_THEME: Theme;
|
|
|
628
694
|
/** A ready-made dark palette — pass as the `theme` prop for a dark-mode `<FormBuilder />`. */
|
|
629
695
|
declare const DARK_THEME: Theme;
|
|
630
696
|
|
|
631
|
-
|
|
697
|
+
declare function serializeTemplate(document: FormDocument): string;
|
|
698
|
+
/** Accepts a `serializeTemplate` envelope or a bare document (e.g. "View JSON" output); `null` if not a document. */
|
|
699
|
+
declare function parseTemplate(raw: string | null | undefined): DocumentFields | null;
|
|
700
|
+
|
|
701
|
+
declare const DRAFT_KEY = "form-page-builder:draft";
|
|
702
|
+
declare const INDEX_KEY = "form-page-builder:index";
|
|
703
|
+
declare const formKey: (id: string) => string;
|
|
704
|
+
/** Template id from a `formKey` result, else null — lets a StorageAdapter route per-template keys. */
|
|
705
|
+
declare const savedFormId: (key: string) => string | null;
|
|
706
|
+
/** Copy/paste-template scratch slot — always localStorage, never the StorageAdapter. */
|
|
707
|
+
declare const CLIPBOARD_KEY = "form-page-builder:clipboard";
|
|
708
|
+
|
|
709
|
+
export { CLIPBOARD_KEY, type CheckboxField, type CheckboxGroupField, type ChromeShape, type ContentBlockType, DARK_THEME, DEFAULT_THEME, DRAFT_KEY, type DocumentFields, type FieldPatch, type FieldType, FormBuilder, type FormBuilderFeatures, type FormBuilderHandle, type FormBuilderProps, type FormDocument, type FormField, type FormTemplate, INDEX_KEY, 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 TemplateChange, type TextareaField, type Theme, type ThemeLayout, type ThemeOverrides, type ToggleField, FormBuilder as default, formKey, localStorageAdapter, parseTemplate, savedFormId, serializeTemplate };
|
package/dist/index.d.ts
CHANGED
|
@@ -103,16 +103,33 @@ declare const CHROME: {
|
|
|
103
103
|
formJson: string;
|
|
104
104
|
copy: string;
|
|
105
105
|
copied: string;
|
|
106
|
+
copyTemplate: string;
|
|
107
|
+
pasteTemplate: string;
|
|
108
|
+
copyTemplateTitle: string;
|
|
109
|
+
pasteTemplateTitle: string;
|
|
110
|
+
pasteTemplateConfirm: string;
|
|
106
111
|
noTemplates: string;
|
|
112
|
+
noTemplatesReadonly: string;
|
|
107
113
|
updated: string;
|
|
108
114
|
open: string;
|
|
115
|
+
applyTemplate: string;
|
|
109
116
|
saveForm: string;
|
|
110
117
|
formName: string;
|
|
111
118
|
saveToLibrary: string;
|
|
112
119
|
loadingDraft: string;
|
|
113
|
-
templatesLimitReached: string;
|
|
120
|
+
templatesLimitReached: (max: number) => string;
|
|
121
|
+
templatesLimitTitle: string;
|
|
122
|
+
confirm: string;
|
|
123
|
+
cancel: string;
|
|
124
|
+
dismiss: string;
|
|
125
|
+
confirmReplace: string;
|
|
114
126
|
current: string;
|
|
115
127
|
customColor: string;
|
|
128
|
+
templateLabel: (name: string) => string;
|
|
129
|
+
templateEdited: string;
|
|
130
|
+
templateLoading: string;
|
|
131
|
+
templateLoadFailed: string;
|
|
132
|
+
templateSaveFailed: string;
|
|
116
133
|
fieldsCount: (n: number) => string;
|
|
117
134
|
fieldTypeInput: string;
|
|
118
135
|
fieldTypeTextarea: string;
|
|
@@ -239,16 +256,33 @@ declare const CHROME: {
|
|
|
239
256
|
formJson: string;
|
|
240
257
|
copy: string;
|
|
241
258
|
copied: string;
|
|
259
|
+
copyTemplate: string;
|
|
260
|
+
pasteTemplate: string;
|
|
261
|
+
copyTemplateTitle: string;
|
|
262
|
+
pasteTemplateTitle: string;
|
|
263
|
+
pasteTemplateConfirm: string;
|
|
242
264
|
noTemplates: string;
|
|
265
|
+
noTemplatesReadonly: string;
|
|
243
266
|
updated: string;
|
|
244
267
|
open: string;
|
|
268
|
+
applyTemplate: string;
|
|
245
269
|
saveForm: string;
|
|
246
270
|
formName: string;
|
|
247
271
|
saveToLibrary: string;
|
|
248
272
|
loadingDraft: string;
|
|
249
|
-
templatesLimitReached: string;
|
|
273
|
+
templatesLimitReached: (max: number) => string;
|
|
274
|
+
templatesLimitTitle: string;
|
|
275
|
+
confirm: string;
|
|
276
|
+
cancel: string;
|
|
277
|
+
dismiss: string;
|
|
278
|
+
confirmReplace: string;
|
|
250
279
|
current: string;
|
|
251
280
|
customColor: string;
|
|
281
|
+
templateLabel: (name: string) => string;
|
|
282
|
+
templateEdited: string;
|
|
283
|
+
templateLoading: string;
|
|
284
|
+
templateLoadFailed: string;
|
|
285
|
+
templateSaveFailed: string;
|
|
252
286
|
fieldsCount: (n: number) => string;
|
|
253
287
|
fieldTypeInput: string;
|
|
254
288
|
fieldTypeTextarea: string;
|
|
@@ -564,12 +598,37 @@ interface FormBuilderHandle {
|
|
|
564
598
|
loadDocument(doc: FormDocument): void;
|
|
565
599
|
/** Convenience for `JSON.stringify(getDocument())`. */
|
|
566
600
|
exportJson(): string;
|
|
601
|
+
/** The current document as a portable `FormTemplate` — pass to another builder's `loadTemplate()` or persist it. */
|
|
602
|
+
getTemplate(): FormTemplate;
|
|
603
|
+
/** Loads a `FormTemplate` (or its JSON, or bare document JSON); `false` if it can't be parsed. */
|
|
604
|
+
loadTemplate(input: FormTemplate | string): boolean;
|
|
605
|
+
}
|
|
606
|
+
/** Self-describing `FormDocument` wrapper; the `__fpb` tag marks it as ours. See `serializeTemplate` / `parseTemplate`. */
|
|
607
|
+
interface FormTemplate {
|
|
608
|
+
__fpb: "template";
|
|
609
|
+
v: number;
|
|
610
|
+
document: FormDocument;
|
|
611
|
+
}
|
|
612
|
+
interface TemplateChange {
|
|
613
|
+
/** Affected template's id; `null` when the active template was just deleted. */
|
|
614
|
+
id: string | null;
|
|
615
|
+
title: string;
|
|
616
|
+
/** `new` = created, `saved` = overwritten, `applied` = loaded as the working doc, `deleted`. */
|
|
617
|
+
source: "new" | "saved" | "applied" | "deleted";
|
|
567
618
|
}
|
|
568
619
|
interface FormBuilderFeatures {
|
|
569
620
|
/** Editable form title input in the Toolbar. Default true. */
|
|
570
621
|
naming?: boolean;
|
|
571
|
-
/**
|
|
572
|
-
|
|
622
|
+
/**
|
|
623
|
+
* Templates library. `true` (default) = full CRUD + toolbar "Save"; `false` = hidden.
|
|
624
|
+
* `{ manage: false }` = pick-and-apply only (no save/overwrite/delete). `{ max }` caps the count (default 5).
|
|
625
|
+
*/
|
|
626
|
+
templates?: boolean | {
|
|
627
|
+
manage?: boolean;
|
|
628
|
+
max?: number;
|
|
629
|
+
};
|
|
630
|
+
/** "Copy template" / "Paste template" icons by "View JSON"; paste enables once another instance copies. Default true. */
|
|
631
|
+
templateClipboard?: boolean;
|
|
573
632
|
/** "New Form" reset button. Default true. */
|
|
574
633
|
newForm?: boolean;
|
|
575
634
|
/** Autosave the draft to `storage`. The initial draft load always happens; this only gates the write path. Default true. */
|
|
@@ -588,10 +647,16 @@ interface FormBuilderFeatures {
|
|
|
588
647
|
contentBlocks?: boolean | ContentBlockType[];
|
|
589
648
|
/** Which form field types can be added from the palette. `true` = all, `false` = none, or an allowlist array. Default true. */
|
|
590
649
|
fieldTypes?: boolean | InputFieldType[];
|
|
591
|
-
/** Add/duplicate/move/delete section controls + section
|
|
650
|
+
/** Add/duplicate/move/delete section controls + the "Add section" button. Default true. */
|
|
592
651
|
sections?: boolean;
|
|
652
|
+
/** Per-section background-color picker. Independent of `sections`; unset → follows `sections`, else true. */
|
|
653
|
+
sectionBackground?: boolean;
|
|
593
654
|
/** Drag-to-reorder fields within a section. Default true. */
|
|
594
655
|
dragReorder?: boolean;
|
|
656
|
+
/** Laptop/Tablet/Mobile width switcher above the Preview canvas. Default true. */
|
|
657
|
+
deviceToggle?: boolean;
|
|
658
|
+
/** Caps the number of input-type fields (not content blocks) addable across the whole document. Default undefined (unlimited). */
|
|
659
|
+
maxFields?: number;
|
|
595
660
|
}
|
|
596
661
|
interface FormBuilderProps {
|
|
597
662
|
theme?: Partial<Theme>;
|
|
@@ -605,21 +670,22 @@ interface FormBuilderProps {
|
|
|
605
670
|
onSubmit?: (payload: SubmitPayload) => void;
|
|
606
671
|
/** Seeds the builder with this document on mount instead of the autosaved draft — e.g. a template fetched from your own backend. */
|
|
607
672
|
initialDocument?: FormDocument;
|
|
673
|
+
/** Which mode the widget mounts into. Default "build". Pair with `features.previewMode: false` to lock a consumer to just one mode with no tabs. */
|
|
674
|
+
initialMode?: "build" | "preview";
|
|
675
|
+
/** Fires on mount and on every Build/Preview toggle — lets a host mirror the current mode without its own tab UI. */
|
|
676
|
+
onModeChange?: (mode: "build" | "preview") => void;
|
|
677
|
+
/** Fires on template create/overwrite/apply/delete — for syncing a host's own state/backend. */
|
|
678
|
+
onTemplateChange?: (change: TemplateChange) => void;
|
|
679
|
+
/** localStorage key behind copy/paste (default `"form-page-builder:clipboard"`); instances sharing it can paste to each other. */
|
|
680
|
+
templateClipboardKey?: string;
|
|
608
681
|
}
|
|
609
682
|
|
|
610
683
|
declare const FormBuilder: react.ForwardRefExoticComponent<FormBuilderProps & react.RefAttributes<FormBuilderHandle>>;
|
|
611
684
|
|
|
612
685
|
/**
|
|
613
|
-
* Default StorageAdapter
|
|
614
|
-
*
|
|
615
|
-
*
|
|
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.
|
|
686
|
+
* Default StorageAdapter over window.localStorage. Availability is checked per-call so it survives SSR.
|
|
687
|
+
* Values are compressed on write; on read, a decompressed result is used only if it parses as JSON,
|
|
688
|
+
* else the raw string is returned (so pre-compression drafts still load).
|
|
623
689
|
*/
|
|
624
690
|
declare const localStorageAdapter: StorageAdapter;
|
|
625
691
|
|
|
@@ -628,4 +694,16 @@ declare const DEFAULT_THEME: Theme;
|
|
|
628
694
|
/** A ready-made dark palette — pass as the `theme` prop for a dark-mode `<FormBuilder />`. */
|
|
629
695
|
declare const DARK_THEME: Theme;
|
|
630
696
|
|
|
631
|
-
|
|
697
|
+
declare function serializeTemplate(document: FormDocument): string;
|
|
698
|
+
/** Accepts a `serializeTemplate` envelope or a bare document (e.g. "View JSON" output); `null` if not a document. */
|
|
699
|
+
declare function parseTemplate(raw: string | null | undefined): DocumentFields | null;
|
|
700
|
+
|
|
701
|
+
declare const DRAFT_KEY = "form-page-builder:draft";
|
|
702
|
+
declare const INDEX_KEY = "form-page-builder:index";
|
|
703
|
+
declare const formKey: (id: string) => string;
|
|
704
|
+
/** Template id from a `formKey` result, else null — lets a StorageAdapter route per-template keys. */
|
|
705
|
+
declare const savedFormId: (key: string) => string | null;
|
|
706
|
+
/** Copy/paste-template scratch slot — always localStorage, never the StorageAdapter. */
|
|
707
|
+
declare const CLIPBOARD_KEY = "form-page-builder:clipboard";
|
|
708
|
+
|
|
709
|
+
export { CLIPBOARD_KEY, type CheckboxField, type CheckboxGroupField, type ChromeShape, type ContentBlockType, DARK_THEME, DEFAULT_THEME, DRAFT_KEY, type DocumentFields, type FieldPatch, type FieldType, FormBuilder, type FormBuilderFeatures, type FormBuilderHandle, type FormBuilderProps, type FormDocument, type FormField, type FormTemplate, INDEX_KEY, 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 TemplateChange, type TextareaField, type Theme, type ThemeLayout, type ThemeOverrides, type ToggleField, FormBuilder as default, formKey, localStorageAdapter, parseTemplate, savedFormId, serializeTemplate };
|