@mapomodule/form 2.0.0-beta.1 → 2.0.0-beta.3
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/dist/__tests__/__mocks__/nuxt-imports.d.ts +4 -0
- package/dist/__tests__/__mocks__/nuxt-imports.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 +167 -13
- package/dist/runtime/components/MapoFocusPortal.vue +113 -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 +108 -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 +86 -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 +157 -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/MapoFileField.vue +97 -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 +118 -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 +97 -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/MapoRepeater.vue +449 -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 +341 -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 +118 -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 +227 -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 +142 -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 +323 -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 +27 -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 +87 -0
- package/dist/runtime/types/descriptor.d.ts +359 -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 +11 -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/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 +3 -3
- package/dist/index.d.cts +0 -1
- package/dist/module.d.cts +0 -2
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { computed, ref } from "vue";
|
|
3
|
+
import {
|
|
4
|
+
parseDateTime,
|
|
5
|
+
CalendarDateTime,
|
|
6
|
+
today,
|
|
7
|
+
getLocalTimeZone
|
|
8
|
+
} from "@internationalized/date";
|
|
9
|
+
const props = defineProps({
|
|
10
|
+
modelValue: { type: null, required: true },
|
|
11
|
+
descriptor: { type: Object, required: true },
|
|
12
|
+
errors: { type: Array, required: false },
|
|
13
|
+
readonly: { type: Boolean, required: false },
|
|
14
|
+
disabled: { type: Boolean, required: false }
|
|
15
|
+
});
|
|
16
|
+
const emit = defineEmits(["update:modelValue"]);
|
|
17
|
+
const open = ref(false);
|
|
18
|
+
const tzMode = computed(() => props.descriptor.attrs?.tz ?? "naive");
|
|
19
|
+
const calendarValue = computed(() => {
|
|
20
|
+
const v = props.modelValue;
|
|
21
|
+
if (!v) return void 0;
|
|
22
|
+
try {
|
|
23
|
+
if (tzMode.value === "utc") {
|
|
24
|
+
const d = new Date(v);
|
|
25
|
+
if (Number.isNaN(d.getTime())) return void 0;
|
|
26
|
+
return new CalendarDateTime(
|
|
27
|
+
d.getFullYear(),
|
|
28
|
+
d.getMonth() + 1,
|
|
29
|
+
d.getDate(),
|
|
30
|
+
d.getHours(),
|
|
31
|
+
d.getMinutes(),
|
|
32
|
+
d.getSeconds()
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
const clean = v.replace(/Z$/, "").replace(/[+-]\d{2}:\d{2}$/, "").split(".")[0];
|
|
36
|
+
return parseDateTime(clean);
|
|
37
|
+
} catch {
|
|
38
|
+
return void 0;
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
function emitFromCalendar(v) {
|
|
42
|
+
if (tzMode.value === "utc") {
|
|
43
|
+
const d = new Date(v.year, v.month - 1, v.day, v.hour, v.minute, 0, 0);
|
|
44
|
+
emit("update:modelValue", d.toISOString());
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
emit("update:modelValue", v.toString());
|
|
48
|
+
}
|
|
49
|
+
const displayLabel = computed(() => {
|
|
50
|
+
const v = calendarValue.value;
|
|
51
|
+
if (!v) return "Select date and time";
|
|
52
|
+
const date = `${String(v.day).padStart(2, "0")}/${String(v.month).padStart(2, "0")}/${v.year}`;
|
|
53
|
+
const time = `${String(v.hour).padStart(2, "0")}:${String(v.minute).padStart(2, "0")}`;
|
|
54
|
+
return `${date} ${time}`;
|
|
55
|
+
});
|
|
56
|
+
const timeHour = computed(() => calendarValue.value?.hour ?? 0);
|
|
57
|
+
const timeMinute = computed(() => calendarValue.value?.minute ?? 0);
|
|
58
|
+
function onDateSelect(date) {
|
|
59
|
+
const d = date;
|
|
60
|
+
if (!d) {
|
|
61
|
+
emit("update:modelValue", null);
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
const h = calendarValue.value?.hour ?? 0;
|
|
65
|
+
const m = calendarValue.value?.minute ?? 0;
|
|
66
|
+
const merged = new CalendarDateTime(d.year, d.month, d.day, h, m);
|
|
67
|
+
emitFromCalendar(merged);
|
|
68
|
+
}
|
|
69
|
+
function onTimeChange(part, val) {
|
|
70
|
+
const n = Math.max(
|
|
71
|
+
0,
|
|
72
|
+
Math.min(part === "hour" ? 23 : 59, parseInt(val) || 0)
|
|
73
|
+
);
|
|
74
|
+
const base = calendarValue.value ?? (() => {
|
|
75
|
+
const t = today(getLocalTimeZone());
|
|
76
|
+
return new CalendarDateTime(t.year, t.month, t.day, 0, 0);
|
|
77
|
+
})();
|
|
78
|
+
const merged = part === "hour" ? new CalendarDateTime(base.year, base.month, base.day, n, base.minute) : new CalendarDateTime(base.year, base.month, base.day, base.hour, n);
|
|
79
|
+
emitFromCalendar(merged);
|
|
80
|
+
}
|
|
81
|
+
function clear() {
|
|
82
|
+
emit("update:modelValue", null);
|
|
83
|
+
open.value = false;
|
|
84
|
+
}
|
|
85
|
+
</script>
|
|
86
|
+
|
|
87
|
+
<template>
|
|
88
|
+
<UPopover v-model:open="open" :disabled="readonly || disabled">
|
|
89
|
+
<UButton
|
|
90
|
+
variant="outline"
|
|
91
|
+
color="neutral"
|
|
92
|
+
icon="i-lucide-calendar"
|
|
93
|
+
trailing
|
|
94
|
+
class="w-full justify-between font-normal"
|
|
95
|
+
:class="{
|
|
96
|
+
'opacity-50 cursor-not-allowed': readonly || disabled,
|
|
97
|
+
'ring-2 ring-red-500': errors?.length
|
|
98
|
+
}"
|
|
99
|
+
:disabled="readonly || disabled"
|
|
100
|
+
>
|
|
101
|
+
<span
|
|
102
|
+
:class="
|
|
103
|
+
calendarValue ? 'text-gray-900 dark:text-white' : 'text-gray-400'
|
|
104
|
+
"
|
|
105
|
+
>
|
|
106
|
+
{{ displayLabel }}
|
|
107
|
+
</span>
|
|
108
|
+
</UButton>
|
|
109
|
+
|
|
110
|
+
<template #content>
|
|
111
|
+
<div class="p-3 space-y-3">
|
|
112
|
+
<UCalendar
|
|
113
|
+
:model-value="calendarValue"
|
|
114
|
+
@update:model-value="onDateSelect"
|
|
115
|
+
/>
|
|
116
|
+
|
|
117
|
+
<!-- Time picker -->
|
|
118
|
+
<div
|
|
119
|
+
class="flex items-center gap-2 border-t border-gray-200 dark:border-gray-700 pt-3"
|
|
120
|
+
>
|
|
121
|
+
<UIcon name="i-lucide-clock" class="text-gray-400 shrink-0" />
|
|
122
|
+
<div class="flex items-center gap-1">
|
|
123
|
+
<UInput
|
|
124
|
+
type="number"
|
|
125
|
+
:model-value="timeHour"
|
|
126
|
+
min="0"
|
|
127
|
+
max="23"
|
|
128
|
+
class="w-14 text-center"
|
|
129
|
+
@update:model-value="
|
|
130
|
+
(v) => onTimeChange('hour', String(v))
|
|
131
|
+
"
|
|
132
|
+
/>
|
|
133
|
+
<span class="text-gray-500 font-medium">:</span>
|
|
134
|
+
<UInput
|
|
135
|
+
type="number"
|
|
136
|
+
:model-value="timeMinute"
|
|
137
|
+
min="0"
|
|
138
|
+
max="59"
|
|
139
|
+
class="w-14 text-center"
|
|
140
|
+
@update:model-value="
|
|
141
|
+
(v) => onTimeChange('minute', String(v))
|
|
142
|
+
"
|
|
143
|
+
/>
|
|
144
|
+
</div>
|
|
145
|
+
<UButton
|
|
146
|
+
variant="ghost"
|
|
147
|
+
color="neutral"
|
|
148
|
+
size="xs"
|
|
149
|
+
icon="i-lucide-x"
|
|
150
|
+
class="ml-auto"
|
|
151
|
+
@click="clear"
|
|
152
|
+
/>
|
|
153
|
+
</div>
|
|
154
|
+
</div>
|
|
155
|
+
</template>
|
|
156
|
+
</UPopover>
|
|
157
|
+
</template>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { DateDescriptor } from "../../types/index.js";
|
|
2
|
+
/** Datetime field with configurable naive/UTC serialisation semantics. */
|
|
3
|
+
type __VLS_Props = {
|
|
4
|
+
modelValue: unknown;
|
|
5
|
+
descriptor: DateDescriptor;
|
|
6
|
+
errors?: string[];
|
|
7
|
+
readonly?: boolean;
|
|
8
|
+
disabled?: boolean;
|
|
9
|
+
};
|
|
10
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
11
|
+
"update:modelValue": (value: string | null) => any;
|
|
12
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
13
|
+
"onUpdate:modelValue"?: ((value: string | null) => any) | undefined;
|
|
14
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
15
|
+
declare const _default: typeof __VLS_export;
|
|
16
|
+
export default _default;
|
|
17
|
+
//# sourceMappingURL=MapoDateTimeField.vue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MapoDateTimeField.vue.d.ts","sourceRoot":"","sources":["../../../../src/runtime/components/fields/MapoDateTimeField.vue"],"names":[],"mappings":"AA0MA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D,0EAA0E;AAC1E,KAAK,WAAW,GAAG;IACjB,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,cAAc,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AA+VF,QAAA,MAAM,YAAY;;;;kFAGhB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { ref, computed } from "vue";
|
|
3
|
+
const props = defineProps({
|
|
4
|
+
modelValue: { type: null, required: true },
|
|
5
|
+
descriptor: { type: Object, required: true },
|
|
6
|
+
errors: { type: Array, required: false },
|
|
7
|
+
readonly: { type: Boolean, required: false },
|
|
8
|
+
disabled: { type: Boolean, required: false }
|
|
9
|
+
});
|
|
10
|
+
const emit = defineEmits(["update:modelValue"]);
|
|
11
|
+
const inputRef = ref(null);
|
|
12
|
+
const currentFileName = computed(() => {
|
|
13
|
+
if (props.modelValue instanceof File) return props.modelValue.name;
|
|
14
|
+
if (typeof props.modelValue === "string" && props.modelValue)
|
|
15
|
+
return props.modelValue.split("/").pop() ?? props.modelValue;
|
|
16
|
+
return null;
|
|
17
|
+
});
|
|
18
|
+
const previewUrl = computed(() => {
|
|
19
|
+
if (props.modelValue instanceof File) {
|
|
20
|
+
if (props.modelValue.type.startsWith("image/"))
|
|
21
|
+
return URL.createObjectURL(props.modelValue);
|
|
22
|
+
}
|
|
23
|
+
if (typeof props.modelValue === "string" && props.modelValue) {
|
|
24
|
+
const ext = props.modelValue.split(".").pop()?.toLowerCase() ?? "";
|
|
25
|
+
if (["jpg", "jpeg", "png", "gif", "webp", "svg", "avif"].includes(ext))
|
|
26
|
+
return props.modelValue;
|
|
27
|
+
}
|
|
28
|
+
return null;
|
|
29
|
+
});
|
|
30
|
+
function onFileChange(e) {
|
|
31
|
+
const file = e.target.files?.[0] ?? null;
|
|
32
|
+
emit("update:modelValue", file);
|
|
33
|
+
}
|
|
34
|
+
function clear() {
|
|
35
|
+
emit("update:modelValue", null);
|
|
36
|
+
if (inputRef.value) inputRef.value.value = "";
|
|
37
|
+
}
|
|
38
|
+
const hasError = computed(() => (props.errors?.length ?? 0) > 0);
|
|
39
|
+
const accept = computed(
|
|
40
|
+
() => props.descriptor.attrs?.accept ?? void 0
|
|
41
|
+
);
|
|
42
|
+
</script>
|
|
43
|
+
|
|
44
|
+
<template>
|
|
45
|
+
<div class="mapo-file-field space-y-2">
|
|
46
|
+
<!-- Current file preview -->
|
|
47
|
+
<div
|
|
48
|
+
v-if="currentFileName"
|
|
49
|
+
class="flex items-center gap-2 rounded border px-3 py-2 text-sm"
|
|
50
|
+
:class="
|
|
51
|
+
hasError ? 'border-red-300 bg-red-50' : 'border-gray-200 bg-gray-50'
|
|
52
|
+
"
|
|
53
|
+
>
|
|
54
|
+
<img
|
|
55
|
+
v-if="previewUrl"
|
|
56
|
+
:src="previewUrl"
|
|
57
|
+
class="h-8 w-8 rounded object-cover shrink-0"
|
|
58
|
+
alt=""
|
|
59
|
+
/>
|
|
60
|
+
<UIcon
|
|
61
|
+
v-else
|
|
62
|
+
name="i-lucide-file"
|
|
63
|
+
class="size-4 shrink-0 text-gray-400"
|
|
64
|
+
/>
|
|
65
|
+
<span class="flex-1 truncate text-gray-700">{{ currentFileName }}</span>
|
|
66
|
+
<UButton
|
|
67
|
+
v-if="!readonly && !disabled"
|
|
68
|
+
size="xs"
|
|
69
|
+
variant="ghost"
|
|
70
|
+
color="neutral"
|
|
71
|
+
icon="i-lucide-x"
|
|
72
|
+
aria-label="Remove file"
|
|
73
|
+
@click="clear"
|
|
74
|
+
/>
|
|
75
|
+
</div>
|
|
76
|
+
|
|
77
|
+
<!-- File input -->
|
|
78
|
+
<UInput
|
|
79
|
+
v-if="!readonly && !disabled"
|
|
80
|
+
ref="inputRef"
|
|
81
|
+
type="file"
|
|
82
|
+
:accept="accept"
|
|
83
|
+
:color="hasError ? 'error' : void 0"
|
|
84
|
+
:aria-invalid="hasError ? 'true' : void 0"
|
|
85
|
+
@change="onFileChange"
|
|
86
|
+
/>
|
|
87
|
+
|
|
88
|
+
<p
|
|
89
|
+
v-for="err in errors"
|
|
90
|
+
:key="err"
|
|
91
|
+
class="text-sm text-red-500"
|
|
92
|
+
role="alert"
|
|
93
|
+
>
|
|
94
|
+
{{ err }}
|
|
95
|
+
</p>
|
|
96
|
+
</div>
|
|
97
|
+
</template>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { FileDescriptor } from "../../types/index.js";
|
|
2
|
+
type __VLS_Props = {
|
|
3
|
+
modelValue: unknown;
|
|
4
|
+
descriptor: FileDescriptor;
|
|
5
|
+
errors?: string[];
|
|
6
|
+
readonly?: boolean;
|
|
7
|
+
disabled?: boolean;
|
|
8
|
+
};
|
|
9
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
10
|
+
"update:modelValue": (value: File | null) => any;
|
|
11
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
12
|
+
"onUpdate:modelValue"?: ((value: File | null) => any) | undefined;
|
|
13
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
14
|
+
declare const _default: typeof __VLS_export;
|
|
15
|
+
export default _default;
|
|
16
|
+
//# sourceMappingURL=MapoFileField.vue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MapoFileField.vue.d.ts","sourceRoot":"","sources":["../../../../src/runtime/components/fields/MapoFileField.vue"],"names":[],"mappings":"AA8GA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D,KAAK,WAAW,GAAG;IACjB,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,cAAc,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AA2MF,QAAA,MAAM,YAAY;;;;kFAGhB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { ref, computed, watch, onMounted } from "vue";
|
|
3
|
+
import { useNuxtApp } from "#app";
|
|
4
|
+
import { debounce } from "@mapomodule/utils";
|
|
5
|
+
const props = defineProps({
|
|
6
|
+
modelValue: { type: null, required: true },
|
|
7
|
+
descriptor: { type: Object, required: true },
|
|
8
|
+
errors: { type: Array, required: false },
|
|
9
|
+
readonly: { type: Boolean, required: false },
|
|
10
|
+
disabled: { type: Boolean, required: false }
|
|
11
|
+
});
|
|
12
|
+
const emit = defineEmits(["update:modelValue"]);
|
|
13
|
+
const attrs = computed(() => props.descriptor.attrs);
|
|
14
|
+
const isMultiple = computed(
|
|
15
|
+
() => props.descriptor.type === "m2m" || !!attrs.value.multiple
|
|
16
|
+
);
|
|
17
|
+
const itemText = computed(() => attrs.value.itemText ?? "name");
|
|
18
|
+
const itemValue = computed(() => attrs.value.itemValue ?? "id");
|
|
19
|
+
const items = ref([]);
|
|
20
|
+
const isLoading = ref(false);
|
|
21
|
+
const searchTerm = ref("");
|
|
22
|
+
const $mapoFetch = useNuxtApp().$mapoFetch;
|
|
23
|
+
async function fetchItems(query) {
|
|
24
|
+
isLoading.value = true;
|
|
25
|
+
try {
|
|
26
|
+
const rawEndpoint = attrs.value.endpoint;
|
|
27
|
+
const endpoint = rawEndpoint.startsWith("/") || rawEndpoint.startsWith("http") ? rawEndpoint : `/${rawEndpoint}`;
|
|
28
|
+
const url = query ? `${endpoint}${endpoint.includes("?") ? "&" : "?"}search=${encodeURIComponent(query)}` : endpoint;
|
|
29
|
+
const data = await ($mapoFetch ?? $fetch)(url);
|
|
30
|
+
const raw = Array.isArray(data) ? data : data.results ?? [];
|
|
31
|
+
items.value = raw;
|
|
32
|
+
} catch {
|
|
33
|
+
items.value = [];
|
|
34
|
+
} finally {
|
|
35
|
+
isLoading.value = false;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
const debouncedFetch = debounce(fetchItems, 300);
|
|
39
|
+
onMounted(() => fetchItems(""));
|
|
40
|
+
watch(searchTerm, (q) => debouncedFetch(q));
|
|
41
|
+
const internalValue = computed({
|
|
42
|
+
get: () => props.modelValue,
|
|
43
|
+
set: (val) => emit("update:modelValue", val)
|
|
44
|
+
});
|
|
45
|
+
const placeholder = computed(
|
|
46
|
+
() => isMultiple.value ? "Search and select..." : "Search..."
|
|
47
|
+
);
|
|
48
|
+
function getLabel(item) {
|
|
49
|
+
if (item !== null && item !== void 0 && typeof item !== "object") {
|
|
50
|
+
const found = items.value.find((i) => i[itemValue.value] === item);
|
|
51
|
+
return found ? String(found[itemText.value] ?? item) : String(item);
|
|
52
|
+
}
|
|
53
|
+
if (!item || typeof item !== "object") return "";
|
|
54
|
+
return String(item[itemText.value] ?? "");
|
|
55
|
+
}
|
|
56
|
+
function getItemKey(item) {
|
|
57
|
+
if (item !== null && item !== void 0 && typeof item !== "object")
|
|
58
|
+
return item;
|
|
59
|
+
return item?.[itemValue.value];
|
|
60
|
+
}
|
|
61
|
+
</script>
|
|
62
|
+
|
|
63
|
+
<template>
|
|
64
|
+
<USelectMenu
|
|
65
|
+
v-model="internalValue"
|
|
66
|
+
v-model:search-term="searchTerm"
|
|
67
|
+
:items="items"
|
|
68
|
+
:label-key="itemText"
|
|
69
|
+
:value-key="attrs.returnObject === false ? itemValue : void 0"
|
|
70
|
+
:by="attrs.returnObject !== false ? itemValue : void 0"
|
|
71
|
+
:multiple="isMultiple"
|
|
72
|
+
:loading="isLoading"
|
|
73
|
+
:ignore-filter="true"
|
|
74
|
+
:placeholder="placeholder"
|
|
75
|
+
:readonly="readonly"
|
|
76
|
+
:disabled="disabled"
|
|
77
|
+
:highlight="!!errors?.length"
|
|
78
|
+
clear
|
|
79
|
+
>
|
|
80
|
+
<!-- Chips for multi-selection -->
|
|
81
|
+
<template
|
|
82
|
+
v-if="isMultiple && Array.isArray(internalValue) && internalValue.length"
|
|
83
|
+
#default
|
|
84
|
+
>
|
|
85
|
+
<div class="flex flex-wrap gap-1 py-0.5">
|
|
86
|
+
<UBadge
|
|
87
|
+
v-for="item in internalValue"
|
|
88
|
+
:key="String(getItemKey(item))"
|
|
89
|
+
variant="soft"
|
|
90
|
+
color="primary"
|
|
91
|
+
class="cursor-default"
|
|
92
|
+
>
|
|
93
|
+
{{ getLabel(item) }}
|
|
94
|
+
<UButton
|
|
95
|
+
v-if="!readonly && !disabled"
|
|
96
|
+
size="xs"
|
|
97
|
+
variant="ghost"
|
|
98
|
+
color="primary"
|
|
99
|
+
icon="i-lucide-x"
|
|
100
|
+
class="-mr-1 ml-0.5 h-3.5 w-3.5"
|
|
101
|
+
@click.stop="
|
|
102
|
+
internalValue = internalValue.filter(
|
|
103
|
+
(i) => getItemKey(i) !== getItemKey(item)
|
|
104
|
+
)
|
|
105
|
+
"
|
|
106
|
+
/>
|
|
107
|
+
</UBadge>
|
|
108
|
+
</div>
|
|
109
|
+
</template>
|
|
110
|
+
|
|
111
|
+
<!-- Empty state -->
|
|
112
|
+
<template #empty>
|
|
113
|
+
<span class="text-sm text-gray-500">
|
|
114
|
+
{{ searchTerm ? "No results found" : "No items available" }}
|
|
115
|
+
</span>
|
|
116
|
+
</template>
|
|
117
|
+
</USelectMenu>
|
|
118
|
+
</template>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { FksDescriptor } from "../../types/index.js";
|
|
2
|
+
type __VLS_Props = {
|
|
3
|
+
modelValue: unknown;
|
|
4
|
+
descriptor: FksDescriptor;
|
|
5
|
+
errors?: string[];
|
|
6
|
+
readonly?: boolean;
|
|
7
|
+
disabled?: boolean;
|
|
8
|
+
};
|
|
9
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
10
|
+
"update:modelValue": (value: unknown) => any;
|
|
11
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
12
|
+
"onUpdate:modelValue"?: ((value: unknown) => any) | undefined;
|
|
13
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
14
|
+
declare const _default: typeof __VLS_export;
|
|
15
|
+
export default _default;
|
|
16
|
+
//# sourceMappingURL=MapoFksField.vue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MapoFksField.vue.d.ts","sourceRoot":"","sources":["../../../../src/runtime/components/fields/MapoFksField.vue"],"names":[],"mappings":"AA6JA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D,KAAK,WAAW,GAAG;IACjB,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,aAAa,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AA4PF,QAAA,MAAM,YAAY;;;;kFAGhB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { ref, computed, defineAsyncComponent } from "vue";
|
|
3
|
+
const LeafletMap = defineAsyncComponent(
|
|
4
|
+
() => import("./MapoMapFieldClient.vue")
|
|
5
|
+
);
|
|
6
|
+
const props = defineProps({
|
|
7
|
+
modelValue: { type: null, required: true },
|
|
8
|
+
descriptor: { type: Object, required: true },
|
|
9
|
+
errors: { type: Array, required: false },
|
|
10
|
+
readonly: { type: Boolean, required: false },
|
|
11
|
+
disabled: { type: Boolean, required: false }
|
|
12
|
+
});
|
|
13
|
+
const emit = defineEmits(["update:modelValue"]);
|
|
14
|
+
const attrs = computed(() => props.descriptor.attrs ?? {});
|
|
15
|
+
const value = computed(() => {
|
|
16
|
+
const v = props.modelValue;
|
|
17
|
+
if (!v || typeof v !== "object") return null;
|
|
18
|
+
const { lat, lng } = v;
|
|
19
|
+
return typeof lat === "number" && typeof lng === "number" ? { lat, lng } : null;
|
|
20
|
+
});
|
|
21
|
+
const latInput = ref(value.value?.lat?.toString() ?? "");
|
|
22
|
+
const lngInput = ref(value.value?.lng?.toString() ?? "");
|
|
23
|
+
function onMapClick(coords) {
|
|
24
|
+
latInput.value = coords.lat.toFixed(6);
|
|
25
|
+
lngInput.value = coords.lng.toFixed(6);
|
|
26
|
+
emit("update:modelValue", coords);
|
|
27
|
+
}
|
|
28
|
+
function onManualInput() {
|
|
29
|
+
const lat = parseFloat(latInput.value);
|
|
30
|
+
const lng = parseFloat(lngInput.value);
|
|
31
|
+
if (!isNaN(lat) && !isNaN(lng)) emit("update:modelValue", { lat, lng });
|
|
32
|
+
}
|
|
33
|
+
function clear() {
|
|
34
|
+
latInput.value = "";
|
|
35
|
+
lngInput.value = "";
|
|
36
|
+
emit("update:modelValue", null);
|
|
37
|
+
}
|
|
38
|
+
</script>
|
|
39
|
+
|
|
40
|
+
<template>
|
|
41
|
+
<div class="mapo-map-field space-y-2">
|
|
42
|
+
<!-- Manual coordinate inputs -->
|
|
43
|
+
<div class="flex gap-2">
|
|
44
|
+
<UInput
|
|
45
|
+
v-model="latInput"
|
|
46
|
+
placeholder="Latitude"
|
|
47
|
+
class="flex-1"
|
|
48
|
+
:readonly="readonly"
|
|
49
|
+
:disabled="disabled"
|
|
50
|
+
@blur="onManualInput"
|
|
51
|
+
/>
|
|
52
|
+
<UInput
|
|
53
|
+
v-model="lngInput"
|
|
54
|
+
placeholder="Longitude"
|
|
55
|
+
class="flex-1"
|
|
56
|
+
:readonly="readonly"
|
|
57
|
+
:disabled="disabled"
|
|
58
|
+
@blur="onManualInput"
|
|
59
|
+
/>
|
|
60
|
+
<UButton
|
|
61
|
+
v-if="value && !readonly && !disabled"
|
|
62
|
+
variant="ghost"
|
|
63
|
+
color="neutral"
|
|
64
|
+
icon="i-lucide-x"
|
|
65
|
+
@click="clear"
|
|
66
|
+
/>
|
|
67
|
+
</div>
|
|
68
|
+
|
|
69
|
+
<!-- Leaflet map (client only) -->
|
|
70
|
+
<ClientOnly>
|
|
71
|
+
<LeafletMap
|
|
72
|
+
:value="value"
|
|
73
|
+
:default-lat="attrs.defaultLat ?? 41.9"
|
|
74
|
+
:default-lng="attrs.defaultLng ?? 12.5"
|
|
75
|
+
:zoom="attrs.zoom ?? 6"
|
|
76
|
+
:readonly="readonly ?? false"
|
|
77
|
+
@click="onMapClick"
|
|
78
|
+
/>
|
|
79
|
+
<template #fallback>
|
|
80
|
+
<div
|
|
81
|
+
class="flex h-48 items-center justify-center rounded border border-gray-200 bg-gray-50 text-sm text-gray-400"
|
|
82
|
+
>
|
|
83
|
+
Loading map...
|
|
84
|
+
</div>
|
|
85
|
+
</template>
|
|
86
|
+
</ClientOnly>
|
|
87
|
+
|
|
88
|
+
<p
|
|
89
|
+
v-for="err in errors"
|
|
90
|
+
:key="err"
|
|
91
|
+
class="text-sm text-red-500"
|
|
92
|
+
role="alert"
|
|
93
|
+
>
|
|
94
|
+
{{ err }}
|
|
95
|
+
</p>
|
|
96
|
+
</div>
|
|
97
|
+
</template>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { MapDescriptor } from "../../types/index.js";
|
|
2
|
+
/** Geographic coordinates stored by the map field. */
|
|
3
|
+
interface LatLng {
|
|
4
|
+
lat: number;
|
|
5
|
+
lng: number;
|
|
6
|
+
}
|
|
7
|
+
/** Map field with manual lat/lng inputs plus a client-only Leaflet picker. */
|
|
8
|
+
type __VLS_Props = {
|
|
9
|
+
modelValue: unknown;
|
|
10
|
+
descriptor: MapDescriptor;
|
|
11
|
+
errors?: string[];
|
|
12
|
+
readonly?: boolean;
|
|
13
|
+
disabled?: boolean;
|
|
14
|
+
};
|
|
15
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
16
|
+
"update:modelValue": (value: LatLng | null) => any;
|
|
17
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
18
|
+
"onUpdate:modelValue"?: ((value: LatLng | null) => any) | undefined;
|
|
19
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
20
|
+
declare const _default: typeof __VLS_export;
|
|
21
|
+
export default _default;
|
|
22
|
+
//# sourceMappingURL=MapoMapField.vue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MapoMapField.vue.d.ts","sourceRoot":"","sources":["../../../../src/runtime/components/fields/MapoMapField.vue"],"names":[],"mappings":"AAyHA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAO1D,sDAAsD;AACtD,UAAU,MAAM;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb;AAED,8EAA8E;AAC9E,KAAK,WAAW,GAAG;IACjB,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,aAAa,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAoOF,QAAA,MAAM,YAAY;;;;kFAGhB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { ref, watch, onMounted, onBeforeUnmount } from "vue";
|
|
3
|
+
const props = defineProps({
|
|
4
|
+
value: { type: [Object, null], required: true },
|
|
5
|
+
defaultLat: { type: Number, required: true },
|
|
6
|
+
defaultLng: { type: Number, required: true },
|
|
7
|
+
zoom: { type: Number, required: true },
|
|
8
|
+
readonly: { type: Boolean, required: true }
|
|
9
|
+
});
|
|
10
|
+
const emit = defineEmits(["click"]);
|
|
11
|
+
const mapEl = ref(null);
|
|
12
|
+
let L = null;
|
|
13
|
+
let map = null;
|
|
14
|
+
let marker = null;
|
|
15
|
+
onMounted(async () => {
|
|
16
|
+
L = (await import("leaflet")).default;
|
|
17
|
+
await import("leaflet/dist/leaflet.css");
|
|
18
|
+
const [iconRetinaUrl, iconUrl, shadowUrl] = await Promise.all([
|
|
19
|
+
import("leaflet/dist/images/marker-icon-2x.png?url").then((m) => m.default),
|
|
20
|
+
import("leaflet/dist/images/marker-icon.png?url").then((m) => m.default),
|
|
21
|
+
import("leaflet/dist/images/marker-shadow.png?url").then((m) => m.default)
|
|
22
|
+
]);
|
|
23
|
+
delete L.Icon.Default.prototype._getIconUrl;
|
|
24
|
+
L.Icon.Default.mergeOptions({ iconRetinaUrl, iconUrl, shadowUrl });
|
|
25
|
+
if (!mapEl.value) return;
|
|
26
|
+
map = L.map(mapEl.value).setView(
|
|
27
|
+
[
|
|
28
|
+
props.value?.lat ?? props.defaultLat,
|
|
29
|
+
props.value?.lng ?? props.defaultLng
|
|
30
|
+
],
|
|
31
|
+
props.zoom
|
|
32
|
+
);
|
|
33
|
+
L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
|
|
34
|
+
attribution: '\xA9 <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>'
|
|
35
|
+
}).addTo(map);
|
|
36
|
+
if (props.value) {
|
|
37
|
+
marker = L.marker([props.value.lat, props.value.lng]).addTo(map);
|
|
38
|
+
}
|
|
39
|
+
if (!props.readonly) {
|
|
40
|
+
map.on("click", (e) => {
|
|
41
|
+
const { lat, lng } = e.latlng;
|
|
42
|
+
if (marker) marker.setLatLng([lat, lng]);
|
|
43
|
+
else if (L && map) marker = L.marker([lat, lng]).addTo(map);
|
|
44
|
+
emit("click", { lat, lng });
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
watch(
|
|
49
|
+
() => props.value,
|
|
50
|
+
(val) => {
|
|
51
|
+
if (!map || !L) return;
|
|
52
|
+
if (val) {
|
|
53
|
+
if (marker) marker.setLatLng([val.lat, val.lng]);
|
|
54
|
+
else marker = L.marker([val.lat, val.lng]).addTo(map);
|
|
55
|
+
map.panTo([val.lat, val.lng]);
|
|
56
|
+
} else {
|
|
57
|
+
marker?.remove();
|
|
58
|
+
marker = null;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
);
|
|
62
|
+
onBeforeUnmount(() => map?.remove());
|
|
63
|
+
</script>
|
|
64
|
+
|
|
65
|
+
<template>
|
|
66
|
+
<div ref="mapEl" class="h-64 w-full rounded border border-gray-200" />
|
|
67
|
+
</template>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/** Geographic coordinates emitted by the interactive Leaflet client. */
|
|
2
|
+
interface LatLng {
|
|
3
|
+
lat: number;
|
|
4
|
+
lng: number;
|
|
5
|
+
}
|
|
6
|
+
type __VLS_Props = {
|
|
7
|
+
value: LatLng | null;
|
|
8
|
+
defaultLat: number;
|
|
9
|
+
defaultLng: number;
|
|
10
|
+
zoom: number;
|
|
11
|
+
readonly: boolean;
|
|
12
|
+
};
|
|
13
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
14
|
+
click: (coords: LatLng) => any;
|
|
15
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
16
|
+
onClick?: ((coords: LatLng) => any) | undefined;
|
|
17
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
18
|
+
declare const _default: typeof __VLS_export;
|
|
19
|
+
export default _default;
|
|
20
|
+
//# sourceMappingURL=MapoMapFieldClient.vue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MapoMapFieldClient.vue.d.ts","sourceRoot":"","sources":["../../../../src/runtime/components/fields/MapoMapFieldClient.vue"],"names":[],"mappings":"AAiGA,wEAAwE;AACxE,UAAU,MAAM;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb;AAED,KAAK,WAAW,GAAG;IACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;CACnB,CAAC;AAuGF,QAAA,MAAM,YAAY;;;;kFAGhB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
|