@mapomodule/form 2.0.0-beta.1 → 2.0.0-beta.10
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/__tests__/__mocks__/nuxt-imports.d.ts +4 -0
- package/dist/__tests__/__mocks__/nuxt-imports.d.ts.map +1 -0
- package/dist/__tests__/camomillaRoundTrip.test.d.ts +2 -0
- package/dist/__tests__/camomillaRoundTrip.test.d.ts.map +1 -0
- package/dist/__tests__/registry.test.d.ts +2 -0
- package/dist/__tests__/registry.test.d.ts.map +1 -0
- package/dist/__tests__/useFormFromSchema.test.d.ts +2 -0
- package/dist/__tests__/useFormFromSchema.test.d.ts.map +1 -0
- package/dist/__tests__/useMapoForm.test.d.ts +2 -0
- package/dist/__tests__/useMapoForm.test.d.ts.map +1 -0
- package/dist/index.d.mts +9 -1
- package/dist/index.d.ts +15 -1
- package/dist/index.d.ts.map +1 -0
- package/dist/index.mjs +7 -34
- package/dist/module.d.mts +20 -2
- package/dist/module.d.ts +12 -2
- package/dist/module.d.ts.map +1 -0
- package/dist/module.json +1 -1
- package/dist/module.mjs +187 -13
- package/dist/runtime/components/MapoFocusPortal.vue +115 -0
- package/dist/runtime/components/MapoFocusPortal.vue.d.ts +4 -0
- package/dist/runtime/components/MapoFocusPortal.vue.d.ts.map +1 -0
- package/dist/runtime/components/MapoForm.vue +168 -0
- package/dist/runtime/components/MapoForm.vue.d.ts +47 -0
- package/dist/runtime/components/MapoForm.vue.d.ts.map +1 -0
- package/dist/runtime/components/MapoFormField.vue +269 -0
- package/dist/runtime/components/MapoFormField.vue.d.ts +46 -0
- package/dist/runtime/components/MapoFormField.vue.d.ts.map +1 -0
- package/dist/runtime/components/MapoFormFlatSection.vue +149 -0
- package/dist/runtime/components/MapoFormFlatSection.vue.d.ts +15 -0
- package/dist/runtime/components/MapoFormFlatSection.vue.d.ts.map +1 -0
- package/dist/runtime/components/MapoFormGroup.vue +247 -0
- package/dist/runtime/components/MapoFormGroup.vue.d.ts +44 -0
- package/dist/runtime/components/MapoFormGroup.vue.d.ts.map +1 -0
- package/dist/runtime/components/MapoFormTabs.vue +110 -0
- package/dist/runtime/components/MapoFormTabs.vue.d.ts +15 -0
- package/dist/runtime/components/MapoFormTabs.vue.d.ts.map +1 -0
- package/dist/runtime/components/MapoUnknownField.vue +62 -0
- package/dist/runtime/components/MapoUnknownField.vue.d.ts +16 -0
- package/dist/runtime/components/MapoUnknownField.vue.d.ts.map +1 -0
- package/dist/runtime/components/fields/MapoDateField.vue +88 -0
- package/dist/runtime/components/fields/MapoDateField.vue.d.ts +17 -0
- package/dist/runtime/components/fields/MapoDateField.vue.d.ts.map +1 -0
- package/dist/runtime/components/fields/MapoDateTimeField.vue +159 -0
- package/dist/runtime/components/fields/MapoDateTimeField.vue.d.ts +17 -0
- package/dist/runtime/components/fields/MapoDateTimeField.vue.d.ts.map +1 -0
- package/dist/runtime/components/fields/MapoEnhancedMediaField.vue +130 -0
- package/dist/runtime/components/fields/MapoEnhancedMediaField.vue.d.ts +16 -0
- package/dist/runtime/components/fields/MapoEnhancedMediaField.vue.d.ts.map +1 -0
- package/dist/runtime/components/fields/MapoFileField.vue +99 -0
- package/dist/runtime/components/fields/MapoFileField.vue.d.ts +16 -0
- package/dist/runtime/components/fields/MapoFileField.vue.d.ts.map +1 -0
- package/dist/runtime/components/fields/MapoFksField.vue +122 -0
- package/dist/runtime/components/fields/MapoFksField.vue.d.ts +16 -0
- package/dist/runtime/components/fields/MapoFksField.vue.d.ts.map +1 -0
- package/dist/runtime/components/fields/MapoMapField.vue +99 -0
- package/dist/runtime/components/fields/MapoMapField.vue.d.ts +22 -0
- package/dist/runtime/components/fields/MapoMapField.vue.d.ts.map +1 -0
- package/dist/runtime/components/fields/MapoMapFieldClient.vue +67 -0
- package/dist/runtime/components/fields/MapoMapFieldClient.vue.d.ts +20 -0
- package/dist/runtime/components/fields/MapoMapFieldClient.vue.d.ts.map +1 -0
- package/dist/runtime/components/fields/MapoMediaField.vue +91 -0
- package/dist/runtime/components/fields/MapoMediaField.vue.d.ts +16 -0
- package/dist/runtime/components/fields/MapoMediaField.vue.d.ts.map +1 -0
- package/dist/runtime/components/fields/MapoMediaM2mField.vue +110 -0
- package/dist/runtime/components/fields/MapoMediaM2mField.vue.d.ts +16 -0
- package/dist/runtime/components/fields/MapoMediaM2mField.vue.d.ts.map +1 -0
- package/dist/runtime/components/fields/MapoMediaUnavailable.vue +15 -0
- package/dist/runtime/components/fields/MapoMediaUnavailable.vue.d.ts +4 -0
- package/dist/runtime/components/fields/MapoMediaUnavailable.vue.d.ts.map +1 -0
- package/dist/runtime/components/fields/MapoRepeater.vue +459 -0
- package/dist/runtime/components/fields/MapoRepeater.vue.d.ts +16 -0
- package/dist/runtime/components/fields/MapoRepeater.vue.d.ts.map +1 -0
- package/dist/runtime/components/fields/MapoRepeaterItem.vue +346 -0
- package/dist/runtime/components/fields/MapoRepeaterItem.vue.d.ts +55 -0
- package/dist/runtime/components/fields/MapoRepeaterItem.vue.d.ts.map +1 -0
- package/dist/runtime/components/fields/MapoSeoPreview.vue +122 -0
- package/dist/runtime/components/fields/MapoSeoPreview.vue.d.ts +22 -0
- package/dist/runtime/components/fields/MapoSeoPreview.vue.d.ts.map +1 -0
- package/dist/runtime/components/fields/MapoTimeField.vue +44 -0
- package/dist/runtime/components/fields/MapoTimeField.vue.d.ts +17 -0
- package/dist/runtime/components/fields/MapoTimeField.vue.d.ts.map +1 -0
- package/dist/runtime/components/fields/MapoWygEditor.vue +252 -0
- package/dist/runtime/components/fields/MapoWygEditor.vue.d.ts +16 -0
- package/dist/runtime/components/fields/MapoWygEditor.vue.d.ts.map +1 -0
- package/dist/runtime/components/fields/nui/NuiCheckbox.vue +9 -0
- package/dist/runtime/components/fields/nui/NuiCheckbox.vue.d.ts +4 -0
- package/dist/runtime/components/fields/nui/NuiCheckbox.vue.d.ts.map +1 -0
- package/dist/runtime/components/fields/nui/NuiInput.vue +9 -0
- package/dist/runtime/components/fields/nui/NuiInput.vue.d.ts +4 -0
- package/dist/runtime/components/fields/nui/NuiInput.vue.d.ts.map +1 -0
- package/dist/runtime/components/fields/nui/NuiSelectMenu.vue +18 -0
- package/dist/runtime/components/fields/nui/NuiSelectMenu.vue.d.ts +4 -0
- package/dist/runtime/components/fields/nui/NuiSelectMenu.vue.d.ts.map +1 -0
- package/dist/runtime/components/fields/nui/NuiSlider.vue +9 -0
- package/dist/runtime/components/fields/nui/NuiSlider.vue.d.ts +4 -0
- package/dist/runtime/components/fields/nui/NuiSlider.vue.d.ts.map +1 -0
- package/dist/runtime/components/fields/nui/NuiSwitch.vue +9 -0
- package/dist/runtime/components/fields/nui/NuiSwitch.vue.d.ts +4 -0
- package/dist/runtime/components/fields/nui/NuiSwitch.vue.d.ts.map +1 -0
- package/dist/runtime/components/fields/nui/NuiTextarea.vue +9 -0
- package/dist/runtime/components/fields/nui/NuiTextarea.vue.d.ts +4 -0
- package/dist/runtime/components/fields/nui/NuiTextarea.vue.d.ts.map +1 -0
- package/dist/runtime/components/fields/nui/useNuiFieldAttrs.d.ts +13 -0
- package/dist/runtime/components/fields/nui/useNuiFieldAttrs.d.ts.map +1 -0
- package/dist/runtime/components/fields/nui/useNuiFieldAttrs.js +19 -0
- package/dist/runtime/composables/defineFormField.d.ts +25 -0
- package/dist/runtime/composables/defineFormField.d.ts.map +1 -0
- package/dist/runtime/composables/defineFormField.js +27 -0
- package/dist/runtime/composables/useCurrentLang.d.ts +6 -0
- package/dist/runtime/composables/useCurrentLang.d.ts.map +1 -0
- package/dist/runtime/composables/useCurrentLang.js +9 -0
- package/dist/runtime/composables/useFocusMode.d.ts +40 -0
- package/dist/runtime/composables/useFocusMode.d.ts.map +1 -0
- package/dist/runtime/composables/useFocusMode.js +31 -0
- package/dist/runtime/composables/useFormDraft.d.ts +60 -0
- package/dist/runtime/composables/useFormDraft.d.ts.map +1 -0
- package/dist/runtime/composables/useFormDraft.js +52 -0
- package/dist/runtime/composables/useFormFromSchema.d.ts +21 -0
- package/dist/runtime/composables/useFormFromSchema.d.ts.map +1 -0
- package/dist/runtime/composables/useFormFromSchema.js +145 -0
- package/dist/runtime/composables/useMapoForm.d.ts +96 -0
- package/dist/runtime/composables/useMapoForm.d.ts.map +1 -0
- package/dist/runtime/composables/useMapoForm.js +325 -0
- package/dist/runtime/composables/useMediaManager.d.ts +17 -0
- package/dist/runtime/composables/useMediaManager.d.ts.map +1 -0
- package/dist/runtime/composables/useMediaManager.js +6 -0
- package/dist/runtime/composables/useProgressiveDisclosure.d.ts +44 -0
- package/dist/runtime/composables/useProgressiveDisclosure.d.ts.map +1 -0
- package/dist/runtime/composables/useProgressiveDisclosure.js +23 -0
- package/dist/runtime/composables/useUnsavedChangesGuard.d.ts +24 -0
- package/dist/runtime/composables/useUnsavedChangesGuard.d.ts.map +1 -0
- package/dist/runtime/composables/useUnsavedChangesGuard.js +28 -0
- package/dist/runtime/devtools/DevtoolsFormsPage.vue +235 -0
- package/dist/runtime/devtools/DevtoolsFormsPage.vue.d.ts +4 -0
- package/dist/runtime/devtools/DevtoolsFormsPage.vue.d.ts.map +1 -0
- package/dist/runtime/plugins/form-registry.d.ts +18 -0
- package/dist/runtime/plugins/form-registry.d.ts.map +1 -0
- package/dist/runtime/plugins/form-registry.js +19 -0
- package/dist/runtime/registry/defaults.d.ts +3 -0
- package/dist/runtime/registry/defaults.d.ts.map +1 -0
- package/dist/runtime/registry/defaults.js +93 -0
- package/dist/runtime/types/descriptor.d.ts +373 -0
- package/dist/runtime/types/descriptor.d.ts.map +1 -0
- package/dist/runtime/types/descriptor.js +26 -0
- package/dist/runtime/types/index.d.ts +12 -0
- package/dist/runtime/types/index.d.ts.map +1 -0
- package/dist/runtime/types/index.js +6 -0
- package/dist/runtime/types/layout.d.ts +21 -0
- package/dist/runtime/types/layout.d.ts.map +1 -0
- package/dist/runtime/types/layout.js +0 -0
- package/dist/runtime/types/media.d.ts +43 -0
- package/dist/runtime/types/media.d.ts.map +1 -0
- package/dist/runtime/types/media.js +0 -0
- package/dist/runtime/types/registry.d.ts +62 -0
- package/dist/runtime/types/registry.d.ts.map +1 -0
- package/dist/runtime/types/registry.js +19 -0
- package/dist/runtime/utils/flattenFieldGroups.d.ts +50 -0
- package/dist/runtime/utils/flattenFieldGroups.d.ts.map +1 -0
- package/dist/runtime/utils/flattenFieldGroups.js +24 -0
- package/dist/types.d.mts +6 -10
- package/package.json +10 -8
- package/src/__tests__/article.schema.json +193 -0
- package/src/__tests__/camomillaRoundTrip.test.ts +73 -0
- package/src/__tests__/useFormFromSchema.test.ts +24 -0
- package/src/__tests__/useMapoForm.test.ts +5 -0
- package/src/index.ts +5 -0
- package/src/module.ts +34 -0
- package/src/runtime/components/MapoFocusPortal.vue +3 -1
- package/src/runtime/components/MapoFormTabs.vue +4 -1
- package/src/runtime/components/fields/MapoDateField.vue +3 -1
- package/src/runtime/components/fields/MapoDateTimeField.vue +3 -1
- package/src/runtime/components/fields/MapoEnhancedMediaField.vue +153 -0
- package/src/runtime/components/fields/MapoFileField.vue +3 -1
- package/src/runtime/components/fields/MapoFksField.vue +7 -2
- package/src/runtime/components/fields/MapoMapField.vue +5 -2
- package/src/runtime/components/fields/MapoMediaField.vue +104 -0
- package/src/runtime/components/fields/MapoMediaM2mField.vue +130 -0
- package/src/runtime/components/fields/MapoMediaUnavailable.vue +19 -0
- package/src/runtime/components/fields/MapoRepeater.vue +33 -26
- package/src/runtime/components/fields/MapoRepeaterItem.vue +14 -8
- package/src/runtime/components/fields/MapoSeoPreview.vue +17 -13
- package/src/runtime/components/fields/MapoWygEditor.vue +47 -5
- package/src/runtime/composables/useFormFromSchema.ts +4 -1
- package/src/runtime/composables/useMapoForm.ts +4 -2
- package/src/runtime/composables/useMediaManager.ts +21 -0
- package/src/runtime/composables/useUnsavedChangesGuard.ts +3 -3
- package/src/runtime/registry/defaults.ts +9 -1
- package/src/runtime/types/descriptor.ts +22 -7
- package/src/runtime/types/index.ts +4 -0
- package/src/runtime/types/media.ts +44 -0
- package/dist/index.d.cts +0 -1
- package/dist/module.d.cts +0 -2
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { definePageMeta, useNuxtApp, useRuntimeConfig } from "#imports";
|
|
3
|
+
import { computed } from "vue";
|
|
4
|
+
definePageMeta({ layout: false });
|
|
5
|
+
const { $mapoFormRegistry } = useNuxtApp();
|
|
6
|
+
const config = useRuntimeConfig().public.mapoForm;
|
|
7
|
+
const registeredTypes = computed(() => {
|
|
8
|
+
const mapping = $mapoFormRegistry?.mapping || {};
|
|
9
|
+
return Object.keys(mapping).sort();
|
|
10
|
+
});
|
|
11
|
+
const builtInTypes = /* @__PURE__ */ new Set([
|
|
12
|
+
"text",
|
|
13
|
+
"textarea",
|
|
14
|
+
"number",
|
|
15
|
+
"boolean",
|
|
16
|
+
"switch",
|
|
17
|
+
"color",
|
|
18
|
+
"file",
|
|
19
|
+
"slider",
|
|
20
|
+
"select",
|
|
21
|
+
"date",
|
|
22
|
+
"time",
|
|
23
|
+
"datetime",
|
|
24
|
+
"fks",
|
|
25
|
+
"m2m",
|
|
26
|
+
"seo",
|
|
27
|
+
"editor",
|
|
28
|
+
"map",
|
|
29
|
+
"repeater"
|
|
30
|
+
]);
|
|
31
|
+
const userMappings = computed(
|
|
32
|
+
() => registeredTypes.value.filter((t) => !builtInTypes.has(t))
|
|
33
|
+
);
|
|
34
|
+
const globalDebounce = computed(() => config?.debounce || 300);
|
|
35
|
+
const globalExpanded = computed(() => config?.groups?.expanded !== false);
|
|
36
|
+
function componentLabel(type) {
|
|
37
|
+
const v = $mapoFormRegistry?.mapping?.[type];
|
|
38
|
+
if (!v) return "\u2014";
|
|
39
|
+
if (typeof v === "string") return v;
|
|
40
|
+
if (typeof v === "function") return "(lazy)";
|
|
41
|
+
if (typeof v === "object") {
|
|
42
|
+
const name = v.__name;
|
|
43
|
+
if (name) return name;
|
|
44
|
+
}
|
|
45
|
+
return "(component)";
|
|
46
|
+
}
|
|
47
|
+
function attrsKeys(type) {
|
|
48
|
+
const a = $mapoFormRegistry?.attrs?.[type];
|
|
49
|
+
return a ? Object.keys(a).join(", ") : "";
|
|
50
|
+
}
|
|
51
|
+
function accessorKeys(type) {
|
|
52
|
+
const ac = $mapoFormRegistry?.accessor?.[type];
|
|
53
|
+
return ac ? Object.keys(ac).join(" / ") : "";
|
|
54
|
+
}
|
|
55
|
+
function isUserType(type) {
|
|
56
|
+
return userMappings.value.includes(type);
|
|
57
|
+
}
|
|
58
|
+
</script>
|
|
59
|
+
|
|
60
|
+
<template>
|
|
61
|
+
<div class="min-h-screen bg-gray-950 text-gray-100 font-mono text-sm p-6">
|
|
62
|
+
<!-- Header -->
|
|
63
|
+
<div class="flex items-center gap-3 mb-8 border-b border-gray-800 pb-4">
|
|
64
|
+
<span class="text-2xl">🗒️</span>
|
|
65
|
+
<div>
|
|
66
|
+
<h1 class="text-lg font-semibold text-white">Mapo Forms</h1>
|
|
67
|
+
<p class="text-gray-400 text-xs">Devtools panel — development only</p>
|
|
68
|
+
</div>
|
|
69
|
+
</div>
|
|
70
|
+
|
|
71
|
+
<div class="grid grid-cols-3 gap-6">
|
|
72
|
+
<!-- Column 1: Global configuration -->
|
|
73
|
+
<div class="col-span-1">
|
|
74
|
+
<h2
|
|
75
|
+
class="text-xs font-semibold text-gray-400 uppercase tracking-wider mb-3"
|
|
76
|
+
>
|
|
77
|
+
Global config
|
|
78
|
+
</h2>
|
|
79
|
+
<div
|
|
80
|
+
class="bg-gray-900 rounded-lg border border-gray-800 p-4 space-y-3"
|
|
81
|
+
>
|
|
82
|
+
<div>
|
|
83
|
+
<span class="text-gray-500">debounce</span>
|
|
84
|
+
<span class="ml-2 text-amber-400">{{ globalDebounce }}ms</span>
|
|
85
|
+
</div>
|
|
86
|
+
<div>
|
|
87
|
+
<span class="text-gray-500">groups.expanded</span>
|
|
88
|
+
<span
|
|
89
|
+
class="ml-2"
|
|
90
|
+
:class="globalExpanded ? 'text-green-400' : 'text-red-400'"
|
|
91
|
+
>
|
|
92
|
+
{{ globalExpanded }}
|
|
93
|
+
</span>
|
|
94
|
+
</div>
|
|
95
|
+
<div>
|
|
96
|
+
<span class="text-gray-500">custom types</span>
|
|
97
|
+
<span class="ml-2 text-blue-400">{{ userMappings.length }}</span>
|
|
98
|
+
</div>
|
|
99
|
+
</div>
|
|
100
|
+
|
|
101
|
+
<!-- User-defined custom types -->
|
|
102
|
+
<h2
|
|
103
|
+
class="text-xs font-semibold text-gray-400 uppercase tracking-wider mb-3 mt-6"
|
|
104
|
+
>
|
|
105
|
+
Registered custom fields
|
|
106
|
+
</h2>
|
|
107
|
+
<div class="bg-gray-900 rounded-lg border border-gray-800 p-4">
|
|
108
|
+
<div
|
|
109
|
+
v-if="userMappings.length === 0"
|
|
110
|
+
class="text-gray-500 text-xs italic"
|
|
111
|
+
>
|
|
112
|
+
No custom types (nuxt.config → mapoForm.fields.mapping)
|
|
113
|
+
</div>
|
|
114
|
+
<div
|
|
115
|
+
v-for="type in userMappings"
|
|
116
|
+
:key="type"
|
|
117
|
+
class="flex items-center gap-2 py-1"
|
|
118
|
+
>
|
|
119
|
+
<span class="w-2 h-2 rounded-full bg-blue-500 shrink-0" />
|
|
120
|
+
<span class="text-blue-300">{{ type }}</span>
|
|
121
|
+
</div>
|
|
122
|
+
</div>
|
|
123
|
+
</div>
|
|
124
|
+
|
|
125
|
+
<!-- Columns 2-3: Full registry -->
|
|
126
|
+
<div class="col-span-2">
|
|
127
|
+
<h2
|
|
128
|
+
class="text-xs font-semibold text-gray-400 uppercase tracking-wider mb-3"
|
|
129
|
+
>
|
|
130
|
+
Field registry
|
|
131
|
+
<span class="ml-2 text-gray-600 normal-case font-normal"
|
|
132
|
+
>({{ registeredTypes.length }} types)</span
|
|
133
|
+
>
|
|
134
|
+
</h2>
|
|
135
|
+
<div
|
|
136
|
+
class="bg-gray-900 rounded-lg border border-gray-800 overflow-hidden"
|
|
137
|
+
>
|
|
138
|
+
<table class="w-full text-xs">
|
|
139
|
+
<thead>
|
|
140
|
+
<tr class="border-b border-gray-800 bg-gray-900/80">
|
|
141
|
+
<th class="text-left px-4 py-2 text-gray-500 font-medium w-8">
|
|
142
|
+
#
|
|
143
|
+
</th>
|
|
144
|
+
<th class="text-left px-4 py-2 text-gray-500 font-medium">
|
|
145
|
+
type
|
|
146
|
+
</th>
|
|
147
|
+
<th class="text-left px-4 py-2 text-gray-500 font-medium">
|
|
148
|
+
component
|
|
149
|
+
</th>
|
|
150
|
+
<th class="text-left px-4 py-2 text-gray-500 font-medium">
|
|
151
|
+
default attrs
|
|
152
|
+
</th>
|
|
153
|
+
<th class="text-left px-4 py-2 text-gray-500 font-medium">
|
|
154
|
+
accessor
|
|
155
|
+
</th>
|
|
156
|
+
</tr>
|
|
157
|
+
</thead>
|
|
158
|
+
<tbody>
|
|
159
|
+
<tr
|
|
160
|
+
v-for="(type, i) in registeredTypes"
|
|
161
|
+
:key="type"
|
|
162
|
+
class="border-b border-gray-800/50 hover:bg-gray-800/40 transition-colors"
|
|
163
|
+
>
|
|
164
|
+
<td class="px-4 py-2 text-gray-600">
|
|
165
|
+
{{ i + 1 }}
|
|
166
|
+
</td>
|
|
167
|
+
<td class="px-4 py-2">
|
|
168
|
+
<span
|
|
169
|
+
class="px-1.5 py-0.5 rounded text-xs"
|
|
170
|
+
:class="
|
|
171
|
+
isUserType(type) ? 'bg-blue-900/50 text-blue-300' : 'bg-gray-800 text-gray-200'
|
|
172
|
+
"
|
|
173
|
+
>{{ type }}</span
|
|
174
|
+
>
|
|
175
|
+
</td>
|
|
176
|
+
<td class="px-4 py-2 text-green-300">
|
|
177
|
+
{{ componentLabel(type) }}
|
|
178
|
+
</td>
|
|
179
|
+
<td class="px-4 py-2 text-gray-400">
|
|
180
|
+
<span v-if="attrsKeys(type)" class="text-amber-300/80">{{
|
|
181
|
+
attrsKeys(type)
|
|
182
|
+
}}</span>
|
|
183
|
+
<span v-else class="text-gray-700">—</span>
|
|
184
|
+
</td>
|
|
185
|
+
<td class="px-4 py-2">
|
|
186
|
+
<span v-if="accessorKeys(type)" class="text-purple-400">{{
|
|
187
|
+
accessorKeys(type)
|
|
188
|
+
}}</span>
|
|
189
|
+
<span v-else class="text-gray-700">—</span>
|
|
190
|
+
</td>
|
|
191
|
+
</tr>
|
|
192
|
+
</tbody>
|
|
193
|
+
</table>
|
|
194
|
+
</div>
|
|
195
|
+
|
|
196
|
+
<!-- Quick reference -->
|
|
197
|
+
<h2
|
|
198
|
+
class="text-xs font-semibold text-gray-400 uppercase tracking-wider mb-3 mt-6"
|
|
199
|
+
>
|
|
200
|
+
Quick reference — add a custom type
|
|
201
|
+
</h2>
|
|
202
|
+
<div class="bg-gray-900 rounded-lg border border-gray-800 p-4">
|
|
203
|
+
<pre
|
|
204
|
+
class="text-xs text-gray-300 overflow-x-auto leading-relaxed"
|
|
205
|
+
><span class="text-gray-500">// nuxt.config.ts</span>
|
|
206
|
+
<span class="text-blue-300">mapoForm</span>: {
|
|
207
|
+
fields: {
|
|
208
|
+
mapping: {
|
|
209
|
+
<span class="text-amber-300">'my-type'</span>: () => import(<span class="text-green-300">'~/components/MyField.vue'</span>),
|
|
210
|
+
},
|
|
211
|
+
attrs: {
|
|
212
|
+
<span class="text-amber-300">'my-type'</span>: { <span class="text-purple-300">someProp</span>: <span class="text-green-300">true</span> },
|
|
213
|
+
},
|
|
214
|
+
},
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
<span class="text-gray-500">// descriptor</span>
|
|
218
|
+
{ key: <span class="text-green-300">'fieldKey'</span>, type: <span class="text-amber-300">'my-type'</span> }</pre>
|
|
219
|
+
</div>
|
|
220
|
+
|
|
221
|
+
<!-- If MapoUnknownField is rendered -->
|
|
222
|
+
<div
|
|
223
|
+
class="mt-4 p-3 bg-amber-900/20 border border-amber-700/40 rounded-lg text-xs text-amber-300"
|
|
224
|
+
>
|
|
225
|
+
<strong>⚠ MapoUnknownField</strong> — if a yellow placeholder appears
|
|
226
|
+
in a form, the type is missing from the registry. Check
|
|
227
|
+
<code class="bg-amber-900/30 px-1 rounded">descriptor.type</code> and
|
|
228
|
+
add the mapping shown above. In development, a
|
|
229
|
+
<code class="bg-amber-900/30 px-1 rounded">console.warn</code> is
|
|
230
|
+
emitted with the full path.
|
|
231
|
+
</div>
|
|
232
|
+
</div>
|
|
233
|
+
</div>
|
|
234
|
+
</div>
|
|
235
|
+
</template>
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
2
|
+
declare const _default: typeof __VLS_export;
|
|
3
|
+
export default _default;
|
|
4
|
+
//# sourceMappingURL=DevtoolsFormsPage.vue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DevtoolsFormsPage.vue.d.ts","sourceRoot":"","sources":["../../../src/runtime/devtools/DevtoolsFormsPage.vue"],"names":[],"mappings":"AAmwBA,QAAA,MAAM,YAAY,+QAChB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { FieldRegistry } from "../types/index.js";
|
|
2
|
+
declare module "#app" {
|
|
3
|
+
interface NuxtApp {
|
|
4
|
+
$mapoFormRegistry: FieldRegistry;
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
declare module "vue" {
|
|
8
|
+
interface ComponentCustomProperties {
|
|
9
|
+
$mapoFormRegistry: FieldRegistry;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
declare const _default: import("#app").Plugin<{
|
|
13
|
+
mapoFormRegistry: FieldRegistry;
|
|
14
|
+
}> & import("#app").ObjectPlugin<{
|
|
15
|
+
mapoFormRegistry: FieldRegistry;
|
|
16
|
+
}>;
|
|
17
|
+
export default _default;
|
|
18
|
+
//# sourceMappingURL=form-registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"form-registry.d.ts","sourceRoot":"","sources":["../../../src/runtime/plugins/form-registry.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAyB,MAAM,mBAAmB,CAAC;AAE9E,OAAO,QAAQ,MAAM,CAAC;IACpB,UAAU,OAAO;QACf,iBAAiB,EAAE,aAAa,CAAC;KAClC;CACF;AAED,OAAO,QAAQ,KAAK,CAAC;IACnB,UAAU,yBAAyB;QACjC,iBAAiB,EAAE,aAAa,CAAC;KAClC;CACF;;;;;;AAED,wBA0BG"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { defineNuxtPlugin, useRuntimeConfig } from "#app";
|
|
2
|
+
import { defaultRegistry } from "../registry/defaults.js";
|
|
3
|
+
export default defineNuxtPlugin(() => {
|
|
4
|
+
const config = useRuntimeConfig();
|
|
5
|
+
const mapoForm = config.public.mapoForm;
|
|
6
|
+
const userAttrs = mapoForm?.fields?.attrs ?? {};
|
|
7
|
+
const mergedAttrs = { ...defaultRegistry.attrs };
|
|
8
|
+
for (const [type, overrides] of Object.entries(userAttrs)) {
|
|
9
|
+
mergedAttrs[type] = { ...mergedAttrs[type] ?? {}, ...overrides };
|
|
10
|
+
}
|
|
11
|
+
const registry = {
|
|
12
|
+
mapping: { ...defaultRegistry.mapping },
|
|
13
|
+
attrs: mergedAttrs,
|
|
14
|
+
accessor: { ...defaultRegistry.accessor }
|
|
15
|
+
};
|
|
16
|
+
return {
|
|
17
|
+
provide: { mapoFormRegistry: registry }
|
|
18
|
+
};
|
|
19
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../../../src/runtime/registry/defaults.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAMvD,eAAO,MAAM,eAAe,EAAE,aAkG7B,CAAC"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
export const defaultRegistry = {
|
|
2
|
+
mapping: {
|
|
3
|
+
// ─── Nuxt UI — thin wrappers that use <UInput> etc. in the template ──────
|
|
4
|
+
text: () => import("../components/fields/nui/NuiInput.vue"),
|
|
5
|
+
textarea: () => import("../components/fields/nui/NuiTextarea.vue"),
|
|
6
|
+
email: () => import("../components/fields/nui/NuiInput.vue"),
|
|
7
|
+
url: () => import("../components/fields/nui/NuiInput.vue"),
|
|
8
|
+
number: () => import("../components/fields/nui/NuiInput.vue"),
|
|
9
|
+
boolean: () => import("../components/fields/nui/NuiCheckbox.vue"),
|
|
10
|
+
switch: () => import("../components/fields/nui/NuiSwitch.vue"),
|
|
11
|
+
slider: () => import("../components/fields/nui/NuiSlider.vue"),
|
|
12
|
+
color: () => import("../components/fields/nui/NuiInput.vue"),
|
|
13
|
+
file: () => import("../components/fields/MapoFileField.vue"),
|
|
14
|
+
// ─── Nuxt UI with specific config ────────────────────────────────────────
|
|
15
|
+
select: () => import("../components/fields/nui/NuiSelectMenu.vue"),
|
|
16
|
+
// ─── Custom Mapo components (non-trivial logic) ───────────────────────────
|
|
17
|
+
date: () => import("../components/fields/MapoDateField.vue"),
|
|
18
|
+
time: () => import("../components/fields/MapoTimeField.vue"),
|
|
19
|
+
datetime: () => import("../components/fields/MapoDateTimeField.vue"),
|
|
20
|
+
fks: () => import("../components/fields/MapoFksField.vue"),
|
|
21
|
+
m2m: () => import("../components/fields/MapoFksField.vue"),
|
|
22
|
+
seo: () => import("../components/fields/MapoSeoPreview.vue"),
|
|
23
|
+
editor: () => import("../components/fields/MapoWygEditor.vue"),
|
|
24
|
+
map: () => import("../components/fields/MapoMapField.vue"),
|
|
25
|
+
repeater: () => import("../components/fields/MapoRepeater.vue"),
|
|
26
|
+
// ─── Media pickers ────────────────────────────────────────────────────────
|
|
27
|
+
// The fields live here with every other field type; the Media Manager they
|
|
28
|
+
// drive ships with @mapomodule/uikit and is resolved at runtime
|
|
29
|
+
// (see useMediaManager). Without uikit they render an explicit notice.
|
|
30
|
+
media: () => import("../components/fields/MapoMediaField.vue"),
|
|
31
|
+
"media-m2m": () => import("../components/fields/MapoMediaM2mField.vue"),
|
|
32
|
+
"enhanced-media": () => import("../components/fields/MapoEnhancedMediaField.vue")
|
|
33
|
+
},
|
|
34
|
+
attrs: {
|
|
35
|
+
// Applied to all fields
|
|
36
|
+
All: {
|
|
37
|
+
class: "w-full"
|
|
38
|
+
},
|
|
39
|
+
number: {
|
|
40
|
+
type: "number"
|
|
41
|
+
},
|
|
42
|
+
email: {
|
|
43
|
+
type: "email"
|
|
44
|
+
},
|
|
45
|
+
url: {
|
|
46
|
+
type: "url"
|
|
47
|
+
},
|
|
48
|
+
color: {
|
|
49
|
+
type: "color"
|
|
50
|
+
},
|
|
51
|
+
select: {
|
|
52
|
+
// NUI v3 uses `labelKey`/`valueKey`; descriptor uses `{ text, value }` convention.
|
|
53
|
+
labelKey: "text",
|
|
54
|
+
valueKey: "value"
|
|
55
|
+
},
|
|
56
|
+
fks: {
|
|
57
|
+
itemValue: "id",
|
|
58
|
+
returnObject: true
|
|
59
|
+
},
|
|
60
|
+
m2m: {
|
|
61
|
+
itemValue: "id",
|
|
62
|
+
returnObject: true,
|
|
63
|
+
multiple: true
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
accessor: {
|
|
67
|
+
// date/time/datetime: conversion handled internally by the Mapo*Field components
|
|
68
|
+
// (ISO string ↔ @internationalized/date CalendarDate/CalendarDateTime).
|
|
69
|
+
seo: {
|
|
70
|
+
// v1 used `permalink` key — accept both `permalink` and `url` aliases, normalise to `permalink`
|
|
71
|
+
get: ({ val }) => {
|
|
72
|
+
const v = val ?? {};
|
|
73
|
+
const { url, ...rest } = v;
|
|
74
|
+
return {
|
|
75
|
+
title: "",
|
|
76
|
+
description: "",
|
|
77
|
+
...rest,
|
|
78
|
+
permalink: rest.permalink ?? url ?? ""
|
|
79
|
+
};
|
|
80
|
+
},
|
|
81
|
+
set: ({ val }) => {
|
|
82
|
+
const v = val ?? {};
|
|
83
|
+
const { url, ...rest } = v;
|
|
84
|
+
return {
|
|
85
|
+
title: "",
|
|
86
|
+
description: "",
|
|
87
|
+
...rest,
|
|
88
|
+
permalink: rest.permalink ?? url ?? ""
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
};
|