@mapomodule/form 2.0.0-beta.0 → 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.
Files changed (194) hide show
  1. package/README.md +2 -1
  2. package/dist/__tests__/__mocks__/nuxt-imports.d.ts +4 -0
  3. package/dist/__tests__/__mocks__/nuxt-imports.d.ts.map +1 -0
  4. package/dist/__tests__/camomillaRoundTrip.test.d.ts +2 -0
  5. package/dist/__tests__/camomillaRoundTrip.test.d.ts.map +1 -0
  6. package/dist/__tests__/registry.test.d.ts +2 -0
  7. package/dist/__tests__/registry.test.d.ts.map +1 -0
  8. package/dist/__tests__/useFormFromSchema.test.d.ts +2 -0
  9. package/dist/__tests__/useFormFromSchema.test.d.ts.map +1 -0
  10. package/dist/__tests__/useMapoForm.test.d.ts +2 -0
  11. package/dist/__tests__/useMapoForm.test.d.ts.map +1 -0
  12. package/dist/index.d.mts +9 -1
  13. package/dist/index.d.ts +15 -1
  14. package/dist/index.d.ts.map +1 -0
  15. package/dist/index.mjs +7 -34
  16. package/dist/module.d.mts +20 -2
  17. package/dist/module.d.ts +12 -2
  18. package/dist/module.d.ts.map +1 -0
  19. package/dist/module.json +1 -1
  20. package/dist/module.mjs +187 -13
  21. package/dist/runtime/components/MapoFocusPortal.vue +115 -0
  22. package/dist/runtime/components/MapoFocusPortal.vue.d.ts +4 -0
  23. package/dist/runtime/components/MapoFocusPortal.vue.d.ts.map +1 -0
  24. package/dist/runtime/components/MapoForm.vue +168 -0
  25. package/dist/runtime/components/MapoForm.vue.d.ts +47 -0
  26. package/dist/runtime/components/MapoForm.vue.d.ts.map +1 -0
  27. package/dist/runtime/components/MapoFormField.vue +269 -0
  28. package/dist/runtime/components/MapoFormField.vue.d.ts +46 -0
  29. package/dist/runtime/components/MapoFormField.vue.d.ts.map +1 -0
  30. package/dist/runtime/components/MapoFormFlatSection.vue +149 -0
  31. package/dist/runtime/components/MapoFormFlatSection.vue.d.ts +15 -0
  32. package/dist/runtime/components/MapoFormFlatSection.vue.d.ts.map +1 -0
  33. package/dist/runtime/components/MapoFormGroup.vue +247 -0
  34. package/dist/runtime/components/MapoFormGroup.vue.d.ts +44 -0
  35. package/dist/runtime/components/MapoFormGroup.vue.d.ts.map +1 -0
  36. package/dist/runtime/components/MapoFormTabs.vue +110 -0
  37. package/dist/runtime/components/MapoFormTabs.vue.d.ts +15 -0
  38. package/dist/runtime/components/MapoFormTabs.vue.d.ts.map +1 -0
  39. package/dist/runtime/components/MapoUnknownField.vue +62 -0
  40. package/dist/runtime/components/MapoUnknownField.vue.d.ts +16 -0
  41. package/dist/runtime/components/MapoUnknownField.vue.d.ts.map +1 -0
  42. package/dist/runtime/components/fields/MapoDateField.vue +88 -0
  43. package/dist/runtime/components/fields/MapoDateField.vue.d.ts +17 -0
  44. package/dist/runtime/components/fields/MapoDateField.vue.d.ts.map +1 -0
  45. package/dist/runtime/components/fields/MapoDateTimeField.vue +159 -0
  46. package/dist/runtime/components/fields/MapoDateTimeField.vue.d.ts +17 -0
  47. package/dist/runtime/components/fields/MapoDateTimeField.vue.d.ts.map +1 -0
  48. package/dist/runtime/components/fields/MapoEnhancedMediaField.vue +130 -0
  49. package/dist/runtime/components/fields/MapoEnhancedMediaField.vue.d.ts +16 -0
  50. package/dist/runtime/components/fields/MapoEnhancedMediaField.vue.d.ts.map +1 -0
  51. package/dist/runtime/components/fields/MapoFileField.vue +99 -0
  52. package/dist/runtime/components/fields/MapoFileField.vue.d.ts +16 -0
  53. package/dist/runtime/components/fields/MapoFileField.vue.d.ts.map +1 -0
  54. package/dist/runtime/components/fields/MapoFksField.vue +122 -0
  55. package/dist/runtime/components/fields/MapoFksField.vue.d.ts +16 -0
  56. package/dist/runtime/components/fields/MapoFksField.vue.d.ts.map +1 -0
  57. package/dist/runtime/components/fields/MapoMapField.vue +99 -0
  58. package/dist/runtime/components/fields/MapoMapField.vue.d.ts +22 -0
  59. package/dist/runtime/components/fields/MapoMapField.vue.d.ts.map +1 -0
  60. package/dist/runtime/components/fields/MapoMapFieldClient.vue +67 -0
  61. package/dist/runtime/components/fields/MapoMapFieldClient.vue.d.ts +20 -0
  62. package/dist/runtime/components/fields/MapoMapFieldClient.vue.d.ts.map +1 -0
  63. package/dist/runtime/components/fields/MapoMediaField.vue +91 -0
  64. package/dist/runtime/components/fields/MapoMediaField.vue.d.ts +16 -0
  65. package/dist/runtime/components/fields/MapoMediaField.vue.d.ts.map +1 -0
  66. package/dist/runtime/components/fields/MapoMediaM2mField.vue +110 -0
  67. package/dist/runtime/components/fields/MapoMediaM2mField.vue.d.ts +16 -0
  68. package/dist/runtime/components/fields/MapoMediaM2mField.vue.d.ts.map +1 -0
  69. package/dist/runtime/components/fields/MapoMediaUnavailable.vue +15 -0
  70. package/dist/runtime/components/fields/MapoMediaUnavailable.vue.d.ts +4 -0
  71. package/dist/runtime/components/fields/MapoMediaUnavailable.vue.d.ts.map +1 -0
  72. package/dist/runtime/components/fields/MapoRepeater.vue +459 -0
  73. package/dist/runtime/components/fields/MapoRepeater.vue.d.ts +16 -0
  74. package/dist/runtime/components/fields/MapoRepeater.vue.d.ts.map +1 -0
  75. package/dist/runtime/components/fields/MapoRepeaterItem.vue +346 -0
  76. package/dist/runtime/components/fields/MapoRepeaterItem.vue.d.ts +55 -0
  77. package/dist/runtime/components/fields/MapoRepeaterItem.vue.d.ts.map +1 -0
  78. package/dist/runtime/components/fields/MapoSeoPreview.vue +122 -0
  79. package/dist/runtime/components/fields/MapoSeoPreview.vue.d.ts +22 -0
  80. package/dist/runtime/components/fields/MapoSeoPreview.vue.d.ts.map +1 -0
  81. package/dist/runtime/components/fields/MapoTimeField.vue +44 -0
  82. package/dist/runtime/components/fields/MapoTimeField.vue.d.ts +17 -0
  83. package/dist/runtime/components/fields/MapoTimeField.vue.d.ts.map +1 -0
  84. package/dist/runtime/components/fields/MapoWygEditor.vue +252 -0
  85. package/dist/runtime/components/fields/MapoWygEditor.vue.d.ts +16 -0
  86. package/dist/runtime/components/fields/MapoWygEditor.vue.d.ts.map +1 -0
  87. package/dist/runtime/components/fields/nui/NuiCheckbox.vue +9 -0
  88. package/dist/runtime/components/fields/nui/NuiCheckbox.vue.d.ts +4 -0
  89. package/dist/runtime/components/fields/nui/NuiCheckbox.vue.d.ts.map +1 -0
  90. package/dist/runtime/components/fields/nui/NuiInput.vue +9 -0
  91. package/dist/runtime/components/fields/nui/NuiInput.vue.d.ts +4 -0
  92. package/dist/runtime/components/fields/nui/NuiInput.vue.d.ts.map +1 -0
  93. package/dist/runtime/components/fields/nui/NuiSelectMenu.vue +18 -0
  94. package/dist/runtime/components/fields/nui/NuiSelectMenu.vue.d.ts +4 -0
  95. package/dist/runtime/components/fields/nui/NuiSelectMenu.vue.d.ts.map +1 -0
  96. package/dist/runtime/components/fields/nui/NuiSlider.vue +9 -0
  97. package/dist/runtime/components/fields/nui/NuiSlider.vue.d.ts +4 -0
  98. package/dist/runtime/components/fields/nui/NuiSlider.vue.d.ts.map +1 -0
  99. package/dist/runtime/components/fields/nui/NuiSwitch.vue +9 -0
  100. package/dist/runtime/components/fields/nui/NuiSwitch.vue.d.ts +4 -0
  101. package/dist/runtime/components/fields/nui/NuiSwitch.vue.d.ts.map +1 -0
  102. package/dist/runtime/components/fields/nui/NuiTextarea.vue +9 -0
  103. package/dist/runtime/components/fields/nui/NuiTextarea.vue.d.ts +4 -0
  104. package/dist/runtime/components/fields/nui/NuiTextarea.vue.d.ts.map +1 -0
  105. package/dist/runtime/components/fields/nui/useNuiFieldAttrs.d.ts +13 -0
  106. package/dist/runtime/components/fields/nui/useNuiFieldAttrs.d.ts.map +1 -0
  107. package/dist/runtime/components/fields/nui/useNuiFieldAttrs.js +19 -0
  108. package/dist/runtime/composables/defineFormField.d.ts +25 -0
  109. package/dist/runtime/composables/defineFormField.d.ts.map +1 -0
  110. package/dist/runtime/composables/defineFormField.js +27 -0
  111. package/dist/runtime/composables/useCurrentLang.d.ts +6 -0
  112. package/dist/runtime/composables/useCurrentLang.d.ts.map +1 -0
  113. package/dist/runtime/composables/useCurrentLang.js +9 -0
  114. package/dist/runtime/composables/useFocusMode.d.ts +40 -0
  115. package/dist/runtime/composables/useFocusMode.d.ts.map +1 -0
  116. package/dist/runtime/composables/useFocusMode.js +31 -0
  117. package/dist/runtime/composables/useFormDraft.d.ts +60 -0
  118. package/dist/runtime/composables/useFormDraft.d.ts.map +1 -0
  119. package/dist/runtime/composables/useFormDraft.js +52 -0
  120. package/dist/runtime/composables/useFormFromSchema.d.ts +21 -0
  121. package/dist/runtime/composables/useFormFromSchema.d.ts.map +1 -0
  122. package/dist/runtime/composables/useFormFromSchema.js +145 -0
  123. package/dist/runtime/composables/useMapoForm.d.ts +96 -0
  124. package/dist/runtime/composables/useMapoForm.d.ts.map +1 -0
  125. package/dist/runtime/composables/useMapoForm.js +325 -0
  126. package/dist/runtime/composables/useMediaManager.d.ts +17 -0
  127. package/dist/runtime/composables/useMediaManager.d.ts.map +1 -0
  128. package/dist/runtime/composables/useMediaManager.js +6 -0
  129. package/dist/runtime/composables/useProgressiveDisclosure.d.ts +44 -0
  130. package/dist/runtime/composables/useProgressiveDisclosure.d.ts.map +1 -0
  131. package/dist/runtime/composables/useProgressiveDisclosure.js +23 -0
  132. package/dist/runtime/composables/useUnsavedChangesGuard.d.ts +24 -0
  133. package/dist/runtime/composables/useUnsavedChangesGuard.d.ts.map +1 -0
  134. package/dist/runtime/composables/useUnsavedChangesGuard.js +28 -0
  135. package/dist/runtime/devtools/DevtoolsFormsPage.vue +235 -0
  136. package/dist/runtime/devtools/DevtoolsFormsPage.vue.d.ts +4 -0
  137. package/dist/runtime/devtools/DevtoolsFormsPage.vue.d.ts.map +1 -0
  138. package/dist/runtime/plugins/form-registry.d.ts +18 -0
  139. package/dist/runtime/plugins/form-registry.d.ts.map +1 -0
  140. package/dist/runtime/plugins/form-registry.js +19 -0
  141. package/dist/runtime/registry/defaults.d.ts +3 -0
  142. package/dist/runtime/registry/defaults.d.ts.map +1 -0
  143. package/dist/runtime/registry/defaults.js +93 -0
  144. package/dist/runtime/types/descriptor.d.ts +373 -0
  145. package/dist/runtime/types/descriptor.d.ts.map +1 -0
  146. package/dist/runtime/types/descriptor.js +26 -0
  147. package/dist/runtime/types/index.d.ts +12 -0
  148. package/dist/runtime/types/index.d.ts.map +1 -0
  149. package/dist/runtime/types/index.js +6 -0
  150. package/dist/runtime/types/layout.d.ts +21 -0
  151. package/dist/runtime/types/layout.d.ts.map +1 -0
  152. package/dist/runtime/types/layout.js +0 -0
  153. package/dist/runtime/types/media.d.ts +43 -0
  154. package/dist/runtime/types/media.d.ts.map +1 -0
  155. package/dist/runtime/types/media.js +0 -0
  156. package/dist/runtime/types/registry.d.ts +62 -0
  157. package/dist/runtime/types/registry.d.ts.map +1 -0
  158. package/dist/runtime/types/registry.js +19 -0
  159. package/dist/runtime/utils/flattenFieldGroups.d.ts +50 -0
  160. package/dist/runtime/utils/flattenFieldGroups.d.ts.map +1 -0
  161. package/dist/runtime/utils/flattenFieldGroups.js +24 -0
  162. package/dist/types.d.mts +6 -10
  163. package/package.json +10 -8
  164. package/src/__tests__/article.schema.json +193 -0
  165. package/src/__tests__/camomillaRoundTrip.test.ts +73 -0
  166. package/src/__tests__/useFormFromSchema.test.ts +24 -0
  167. package/src/__tests__/useMapoForm.test.ts +5 -0
  168. package/src/index.ts +5 -0
  169. package/src/module.ts +34 -0
  170. package/src/runtime/components/MapoFocusPortal.vue +3 -1
  171. package/src/runtime/components/MapoFormTabs.vue +4 -1
  172. package/src/runtime/components/fields/MapoDateField.vue +3 -1
  173. package/src/runtime/components/fields/MapoDateTimeField.vue +3 -1
  174. package/src/runtime/components/fields/MapoEnhancedMediaField.vue +153 -0
  175. package/src/runtime/components/fields/MapoFileField.vue +3 -1
  176. package/src/runtime/components/fields/MapoFksField.vue +7 -2
  177. package/src/runtime/components/fields/MapoMapField.vue +5 -2
  178. package/src/runtime/components/fields/MapoMediaField.vue +104 -0
  179. package/src/runtime/components/fields/MapoMediaM2mField.vue +130 -0
  180. package/src/runtime/components/fields/MapoMediaUnavailable.vue +19 -0
  181. package/src/runtime/components/fields/MapoRepeater.vue +33 -26
  182. package/src/runtime/components/fields/MapoRepeaterItem.vue +14 -8
  183. package/src/runtime/components/fields/MapoSeoPreview.vue +17 -13
  184. package/src/runtime/components/fields/MapoWygEditor.vue +47 -5
  185. package/src/runtime/composables/useFormFromSchema.ts +4 -1
  186. package/src/runtime/composables/useMapoForm.ts +4 -2
  187. package/src/runtime/composables/useMediaManager.ts +21 -0
  188. package/src/runtime/composables/useUnsavedChangesGuard.ts +3 -3
  189. package/src/runtime/registry/defaults.ts +9 -1
  190. package/src/runtime/types/descriptor.ts +22 -7
  191. package/src/runtime/types/index.ts +4 -0
  192. package/src/runtime/types/media.ts +44 -0
  193. package/dist/index.d.cts +0 -1
  194. 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,3 @@
1
+ import type { FieldRegistry } from "../types/index.js";
2
+ export declare const defaultRegistry: FieldRegistry;
3
+ //# sourceMappingURL=defaults.d.ts.map
@@ -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
+ };