@teamnovu/nuxt-statamic-formbuilder 0.1.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 +13 -0
- package/dist/module.d.mts +14 -0
- package/dist/module.json +9 -0
- package/dist/module.mjs +83 -0
- package/dist/runtime/components/FormBuilderFields.d.vue.ts +34 -0
- package/dist/runtime/components/FormBuilderFields.vue +86 -0
- package/dist/runtime/components/FormBuilderFields.vue.d.ts +34 -0
- package/dist/runtime/components/StatamicFormBuilder.d.vue.ts +26 -0
- package/dist/runtime/components/StatamicFormBuilder.vue +54 -0
- package/dist/runtime/components/StatamicFormBuilder.vue.d.ts +26 -0
- package/dist/runtime/composables/useFieldConditions.d.ts +16 -0
- package/dist/runtime/composables/useFieldConditions.js +230 -0
- package/dist/runtime/composables/useFormBuilder.d.ts +11 -0
- package/dist/runtime/composables/useFormBuilder.js +68 -0
- package/dist/runtime/composables/useFormFieldRegistry.d.ts +8 -0
- package/dist/runtime/composables/useFormFieldRegistry.js +14 -0
- package/dist/runtime/composables/useFormValidation.d.ts +11 -0
- package/dist/runtime/composables/useFormValidation.js +166 -0
- package/dist/runtime/composables/useTranslatableInput.d.ts +8 -0
- package/dist/runtime/composables/useTranslatableInput.js +14 -0
- package/dist/runtime/fieldConfigs.d.ts +91 -0
- package/dist/runtime/fieldConfigs.js +0 -0
- package/dist/runtime/injectionKeys.d.ts +6 -0
- package/dist/runtime/injectionKeys.js +1 -0
- package/dist/runtime/locales/de.json +29 -0
- package/dist/runtime/locales/en.json +29 -0
- package/dist/runtime/locales/fr.json +29 -0
- package/dist/runtime/styles/form-builder.css +1 -0
- package/dist/runtime/types.d.ts +126 -0
- package/dist/runtime/types.js +22 -0
- package/dist/runtime/utils/graphqlFragment.d.ts +5 -0
- package/dist/runtime/utils/graphqlFragment.js +37 -0
- package/dist/runtime/utils/removePTags.d.ts +1 -0
- package/dist/runtime/utils/removePTags.js +4 -0
- package/dist/runtime/utils/submitStatamicForm.d.ts +7 -0
- package/dist/runtime/utils/submitStatamicForm.js +64 -0
- package/dist/runtime/utils/toFormBuilderConfiguration.d.ts +7 -0
- package/dist/runtime/utils/toFormBuilderConfiguration.js +37 -0
- package/dist/types.d.mts +5 -0
- package/package.json +65 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export const COMPONENT_FORM_BUILDER_FRAGMENT = (
|
|
2
|
+
/* GraphQL */
|
|
3
|
+
`
|
|
4
|
+
fragment ComponentFormBuilder on Fieldset_ComponentFormBuilder {
|
|
5
|
+
__typename
|
|
6
|
+
id
|
|
7
|
+
type
|
|
8
|
+
send_button_text
|
|
9
|
+
form {
|
|
10
|
+
__typename
|
|
11
|
+
handle
|
|
12
|
+
honeypot
|
|
13
|
+
rules
|
|
14
|
+
title
|
|
15
|
+
sections {
|
|
16
|
+
__typename
|
|
17
|
+
display
|
|
18
|
+
instructions
|
|
19
|
+
fields {
|
|
20
|
+
__typename
|
|
21
|
+
config
|
|
22
|
+
display
|
|
23
|
+
handle
|
|
24
|
+
instructions
|
|
25
|
+
type
|
|
26
|
+
width
|
|
27
|
+
if
|
|
28
|
+
unless
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
message_loading
|
|
33
|
+
message_success
|
|
34
|
+
message_error
|
|
35
|
+
}
|
|
36
|
+
`
|
|
37
|
+
);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function removePTags(html?: string): string | null;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
const getCookie = (name) => {
|
|
2
|
+
const match = document.cookie.match(
|
|
3
|
+
new RegExp(`(^|;\\s*)(${name})=([^;]*)`)
|
|
4
|
+
);
|
|
5
|
+
return match ? decodeURIComponent(match[3] ?? "") : null;
|
|
6
|
+
};
|
|
7
|
+
function flattenFields(form) {
|
|
8
|
+
if ("fields" in form) {
|
|
9
|
+
return form.fields;
|
|
10
|
+
}
|
|
11
|
+
return form.sections.flatMap((section) => section.fields);
|
|
12
|
+
}
|
|
13
|
+
export async function submitStatamicForm(args) {
|
|
14
|
+
const { form, state, serverUrl, locale } = args;
|
|
15
|
+
if (!serverUrl) {
|
|
16
|
+
throw new Error("[nuxt-statamic-formbuilder] No serverUrl configured for Statamic submit");
|
|
17
|
+
}
|
|
18
|
+
await fetch(`${serverUrl}/sanctum/csrf-cookie`, {
|
|
19
|
+
credentials: "include"
|
|
20
|
+
});
|
|
21
|
+
const token = getCookie("XSRF-TOKEN");
|
|
22
|
+
if (!token) {
|
|
23
|
+
throw new Error("No CSRF token found");
|
|
24
|
+
}
|
|
25
|
+
const formData = new FormData();
|
|
26
|
+
formData.append("_site", locale);
|
|
27
|
+
Object.entries(state).forEach(([key, value]) => {
|
|
28
|
+
if (value?.[0]?.size || value?.[1]?.size) {
|
|
29
|
+
for (let x = 0; x < value.length; x++) {
|
|
30
|
+
formData.append(`${key}[${x}]`, value[x]);
|
|
31
|
+
}
|
|
32
|
+
} else if (value != null) {
|
|
33
|
+
formData.append(key, value);
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
flattenFields(form).filter((field) => ["checkboxes", "input_checkboxes"].includes(field.type)).forEach((field) => {
|
|
37
|
+
const copy = [...formData.entries().filter(([key]) => key?.startsWith("["))];
|
|
38
|
+
copy.forEach(([key, value]) => {
|
|
39
|
+
formData.delete(key);
|
|
40
|
+
const newKey = key.replace(`[${field.handle}]`, field.handle);
|
|
41
|
+
formData.append(newKey, value);
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
const response = await fetch(
|
|
45
|
+
`${serverUrl}/!/forms/${form.handle}`,
|
|
46
|
+
{
|
|
47
|
+
method: "POST",
|
|
48
|
+
credentials: "include",
|
|
49
|
+
headers: {
|
|
50
|
+
"Accept": "application/json",
|
|
51
|
+
"X-Requested-With": "XMLHttpRequest",
|
|
52
|
+
"X-XSRF-TOKEN": token
|
|
53
|
+
},
|
|
54
|
+
body: formData
|
|
55
|
+
}
|
|
56
|
+
);
|
|
57
|
+
if (!response.ok) {
|
|
58
|
+
const body = await response.json().catch(() => void 0);
|
|
59
|
+
const error = new Error(`HTTP error! status: ${response.status}`);
|
|
60
|
+
error.body = body;
|
|
61
|
+
throw error;
|
|
62
|
+
}
|
|
63
|
+
return await response.json().catch(() => void 0);
|
|
64
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { FormBuilderConfiguration } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Cast a GraphQL Form payload into FormBuilderConfiguration.
|
|
4
|
+
* Statamic exposes `config` / `rules` as Array scalars — callers typically
|
|
5
|
+
* already receive the right shape after codegen.
|
|
6
|
+
*/
|
|
7
|
+
export declare function toFormBuilderConfiguration(form: unknown): FormBuilderConfiguration | undefined;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
function normalizeField(field) {
|
|
2
|
+
const config = field.config;
|
|
3
|
+
const normalizedConfig = Array.isArray(config) || config == null ? {} : config;
|
|
4
|
+
return {
|
|
5
|
+
...field,
|
|
6
|
+
config: {
|
|
7
|
+
...normalizedConfig,
|
|
8
|
+
// Editors often only set Statamic `display`; fieldtype `label` may be empty.
|
|
9
|
+
label: normalizedConfig.label ?? field.display ?? void 0
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
export function toFormBuilderConfiguration(form) {
|
|
14
|
+
if (!form || typeof form !== "object") {
|
|
15
|
+
return void 0;
|
|
16
|
+
}
|
|
17
|
+
const candidate = form;
|
|
18
|
+
if (!candidate.handle) {
|
|
19
|
+
return void 0;
|
|
20
|
+
}
|
|
21
|
+
if ("fields" in candidate && Array.isArray(candidate.fields)) {
|
|
22
|
+
return {
|
|
23
|
+
...form,
|
|
24
|
+
fields: candidate.fields.map(normalizeField)
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
if ("sections" in candidate && Array.isArray(candidate.sections)) {
|
|
28
|
+
return {
|
|
29
|
+
...form,
|
|
30
|
+
sections: candidate.sections.map((section) => ({
|
|
31
|
+
...section,
|
|
32
|
+
fields: (section.fields ?? []).map(normalizeField)
|
|
33
|
+
}))
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
return form;
|
|
37
|
+
}
|
package/dist/types.d.mts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { type BaseFieldConfig, type DefaultInputField, type DisplayTextFieldConfig, type FormBuilderConfiguration, type FormBuilderField, type FormBuilderFieldBase, type FormBuilderFieldType, type FormBuilderRequestState, type FormBuilderSubmitter, type FormBuilderTexts, type FormFieldOption, type InputCheckboxesFieldConfig, type InputDateFieldConfig, type InputEmailFieldConfig, type InputFileUploadFieldConfig, type InputFormBuilderField, type InputNumberFieldConfig, type InputPhoneFieldConfig, type InputRadioButtonsFieldConfig, type InputRules, type InputSelectFieldConfig, type InputSliderFieldConfig, type InputSwitchFieldConfig, type InputTextFieldConfig, type InputTextareaFieldConfig, type TranslatableInput, type UseFormBuilderOptions, type ValidationTrigger, type defaultInputField, type formBuilderStateKey, type isDisplayOrSpacerField, type isFileUploadField, type isInputField, type isMultiValueField } from '../dist/runtime/types.js'
|
|
2
|
+
|
|
3
|
+
export { default } from './module.mjs'
|
|
4
|
+
|
|
5
|
+
export { type ModuleOptions } from './module.mjs'
|
package/package.json
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@teamnovu/nuxt-statamic-formbuilder",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Headless Nuxt form builder with Statamic submit adapter",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/types.d.mts",
|
|
10
|
+
"import": "./dist/module.mjs"
|
|
11
|
+
},
|
|
12
|
+
"./style.css": "./dist/runtime/styles/form-builder.css",
|
|
13
|
+
"./runtime/*": {
|
|
14
|
+
"types": "./dist/runtime/*.d.ts",
|
|
15
|
+
"import": "./dist/runtime/*"
|
|
16
|
+
},
|
|
17
|
+
"./runtime/types": {
|
|
18
|
+
"types": "./dist/runtime/types.d.ts",
|
|
19
|
+
"import": "./dist/runtime/types.js"
|
|
20
|
+
},
|
|
21
|
+
"./runtime/composables/*": {
|
|
22
|
+
"types": "./dist/runtime/composables/*.d.ts",
|
|
23
|
+
"import": "./dist/runtime/composables/*"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"main": "./dist/module.mjs",
|
|
27
|
+
"typesVersions": {
|
|
28
|
+
"*": {
|
|
29
|
+
".": [
|
|
30
|
+
"./dist/types.d.mts"
|
|
31
|
+
]
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"files": [
|
|
35
|
+
"dist"
|
|
36
|
+
],
|
|
37
|
+
"publishConfig": {
|
|
38
|
+
"access": "public"
|
|
39
|
+
},
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"@nuxt/kit": "^4.3.1",
|
|
42
|
+
"valibot": "^1.2.0"
|
|
43
|
+
},
|
|
44
|
+
"peerDependencies": {
|
|
45
|
+
"@nuxtjs/i18n": ">=9",
|
|
46
|
+
"nuxt": ">=3.16",
|
|
47
|
+
"vue-i18n": ">=9"
|
|
48
|
+
},
|
|
49
|
+
"devDependencies": {
|
|
50
|
+
"@nuxt/module-builder": "^1.0.2",
|
|
51
|
+
"@nuxt/schema": "^4.3.1",
|
|
52
|
+
"@nuxtjs/i18n": "^10.2.3",
|
|
53
|
+
"@types/node": "^24.11.0",
|
|
54
|
+
"eslint": "^10.0.2",
|
|
55
|
+
"nuxt": "^4.3.1",
|
|
56
|
+
"typescript": "^5.9.3",
|
|
57
|
+
"vue": "^3.5.13",
|
|
58
|
+
"vue-i18n": "^11.4.6",
|
|
59
|
+
"vue-tsc": "^3.3.7"
|
|
60
|
+
},
|
|
61
|
+
"scripts": {
|
|
62
|
+
"dev:prepare": "nuxt-module-build build --stub && nuxt-module-build prepare",
|
|
63
|
+
"lint": "eslint ."
|
|
64
|
+
}
|
|
65
|
+
}
|