@type32/yaml-editor-form 1.0.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.
@@ -0,0 +1,8 @@
1
+ import * as _nuxt_schema from '@nuxt/schema';
2
+
3
+ interface ModuleOptions {
4
+ }
5
+ declare const _default: _nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
6
+
7
+ export { _default as default };
8
+ export type { ModuleOptions };
@@ -0,0 +1,9 @@
1
+ {
2
+ "name": "@type32/yaml-editor-form",
3
+ "configKey": "yamlEditorForm",
4
+ "version": "1.0.0",
5
+ "builder": {
6
+ "@nuxt/module-builder": "1.0.2",
7
+ "unbuild": "unknown"
8
+ }
9
+ }
@@ -0,0 +1,21 @@
1
+ import { defineNuxtModule, createResolver, addComponentsDir, addImportsDir } from '@nuxt/kit';
2
+
3
+ const module$1 = defineNuxtModule({
4
+ meta: {
5
+ name: "@type32/yaml-editor-form",
6
+ configKey: "yamlEditorForm"
7
+ },
8
+ // Default configuration options of the Nuxt module
9
+ defaults: {},
10
+ setup(_options, _nuxt) {
11
+ const resolver = createResolver(import.meta.url);
12
+ addComponentsDir({ path: resolver.resolve("runtime/components") });
13
+ addImportsDir(resolver.resolve("runtime/composables"));
14
+ _nuxt.options.build.transpile.push("yaml");
15
+ _nuxt.options.alias["@type32/yaml-editor-form"] = resolver.resolve(
16
+ "./runtime/types/types"
17
+ );
18
+ }
19
+ });
20
+
21
+ export { module$1 as default };
@@ -0,0 +1,41 @@
1
+ declare var __VLS_13: {}, __VLS_15: {}, __VLS_18: {};
2
+ type __VLS_Slots = {} & {
3
+ badge?: (props: typeof __VLS_13) => any;
4
+ } & {
5
+ actions?: (props: typeof __VLS_15) => any;
6
+ } & {
7
+ default?: (props: typeof __VLS_18) => any;
8
+ };
9
+ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
10
+ label: {
11
+ type: StringConstructor;
12
+ required: true;
13
+ };
14
+ defaultOpen: {
15
+ type: BooleanConstructor;
16
+ default: boolean;
17
+ };
18
+ }>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
19
+ "update:open": (value: boolean) => any;
20
+ }, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
21
+ label: {
22
+ type: StringConstructor;
23
+ required: true;
24
+ };
25
+ defaultOpen: {
26
+ type: BooleanConstructor;
27
+ default: boolean;
28
+ };
29
+ }>> & Readonly<{
30
+ "onUpdate:open"?: ((value: boolean) => any) | undefined;
31
+ }>, {
32
+ defaultOpen: boolean;
33
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
34
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
35
+ declare const _default: typeof __VLS_export;
36
+ export default _default;
37
+ type __VLS_WithSlots<T, S> = T & {
38
+ new (): {
39
+ $slots: S;
40
+ };
41
+ };
@@ -0,0 +1,43 @@
1
+ <script setup>
2
+ defineProps({
3
+ label: {
4
+ type: String,
5
+ required: true
6
+ },
7
+ defaultOpen: {
8
+ type: Boolean,
9
+ default: false
10
+ }
11
+ });
12
+ const open = defineModel("open", { type: Boolean, default: void 0 });
13
+ </script>
14
+
15
+ <template>
16
+ <UCollapsible
17
+ v-model:open="open"
18
+ :default-open="defaultOpen"
19
+ class="group/collapsible"
20
+ >
21
+ <div class="flex items-center justify-between gap-2 w-full">
22
+ <div class="flex items-center gap-2">
23
+ <div
24
+ class="flex items-center justify-center size-3.5 rounded bg-elevated transition-colors duration-200 group-hover/collapsible:bg-accented">
25
+ <UIcon
26
+ name="i-lucide-chevron-right"
27
+ class="size-2.5 text-muted transition-transform duration-200 group-data-[state=open]/collapsible:rotate-90"
28
+ />
29
+ </div>
30
+ <span class="text-xs font-medium text-highlighted tracking-tight">{{ label }}</span>
31
+ <slot name="badge"/>
32
+ </div>
33
+
34
+ <slot name="actions"/>
35
+ </div>
36
+
37
+ <template #content>
38
+ <div class="mt-1 ml-2 pl-3 border-l border-gray-200 dark:border-gray-700/50">
39
+ <slot/>
40
+ </div>
41
+ </template>
42
+ </UCollapsible>
43
+ </template>
@@ -0,0 +1,41 @@
1
+ declare var __VLS_13: {}, __VLS_15: {}, __VLS_18: {};
2
+ type __VLS_Slots = {} & {
3
+ badge?: (props: typeof __VLS_13) => any;
4
+ } & {
5
+ actions?: (props: typeof __VLS_15) => any;
6
+ } & {
7
+ default?: (props: typeof __VLS_18) => any;
8
+ };
9
+ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
10
+ label: {
11
+ type: StringConstructor;
12
+ required: true;
13
+ };
14
+ defaultOpen: {
15
+ type: BooleanConstructor;
16
+ default: boolean;
17
+ };
18
+ }>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
19
+ "update:open": (value: boolean) => any;
20
+ }, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
21
+ label: {
22
+ type: StringConstructor;
23
+ required: true;
24
+ };
25
+ defaultOpen: {
26
+ type: BooleanConstructor;
27
+ default: boolean;
28
+ };
29
+ }>> & Readonly<{
30
+ "onUpdate:open"?: ((value: boolean) => any) | undefined;
31
+ }>, {
32
+ defaultOpen: boolean;
33
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
34
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
35
+ declare const _default: typeof __VLS_export;
36
+ export default _default;
37
+ type __VLS_WithSlots<T, S> = T & {
38
+ new (): {
39
+ $slots: S;
40
+ };
41
+ };
@@ -0,0 +1,37 @@
1
+ import type { YamlFieldType } from "../types/types.js";
2
+ type YamlValue = string | number | boolean | null | Date | YamlValue[] | {
3
+ [key: string]: YamlValue;
4
+ };
5
+ type __VLS_Props = {
6
+ /** Type of the field (string, number, boolean, etc.) */
7
+ valueType: string;
8
+ /** Whether the field is read-only */
9
+ readonly?: boolean;
10
+ /** Optional field type definition for custom component detection */
11
+ fieldType?: YamlFieldType;
12
+ };
13
+ type __VLS_ModelProps = {
14
+ modelValue: YamlValue;
15
+ };
16
+ type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
17
+ declare var __VLS_2: any, __VLS_3: {
18
+ modelValue: YamlValue;
19
+ readonly: boolean;
20
+ valueType: string;
21
+ };
22
+ type __VLS_Slots = {} & {
23
+ [K in NonNullable<typeof __VLS_2>]?: (props: typeof __VLS_3) => any;
24
+ };
25
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
26
+ "update:modelValue": (value: YamlValue) => any;
27
+ }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
28
+ "onUpdate:modelValue"?: ((value: YamlValue) => any) | undefined;
29
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
30
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
31
+ declare const _default: typeof __VLS_export;
32
+ export default _default;
33
+ type __VLS_WithSlots<T, S> = T & {
34
+ new (): {
35
+ $slots: S;
36
+ };
37
+ };
@@ -0,0 +1,157 @@
1
+ <script setup>
2
+ import { CalendarDate, CalendarDateTime, parseDate, parseDateTime } from "@internationalized/date";
3
+ const modelValue = defineModel({ type: [String, Number, Boolean, null, Date, Array, Object], ...{ required: true } });
4
+ const props = defineProps({
5
+ valueType: { type: String, required: true },
6
+ readonly: { type: Boolean, required: false, default: false },
7
+ fieldType: { type: Object, required: false }
8
+ });
9
+ function isDateObject(val) {
10
+ return val instanceof Date && !isNaN(val.getTime());
11
+ }
12
+ function jsDateToCalendarDate(date) {
13
+ return new CalendarDate(date.getFullYear(), date.getMonth() + 1, date.getDate());
14
+ }
15
+ function jsDateToCalendarDateTime(date) {
16
+ return new CalendarDateTime(
17
+ date.getFullYear(),
18
+ date.getMonth() + 1,
19
+ date.getDate(),
20
+ date.getHours(),
21
+ date.getMinutes(),
22
+ date.getSeconds()
23
+ );
24
+ }
25
+ function stringToCalendarDate(str) {
26
+ try {
27
+ return parseDate(str);
28
+ } catch {
29
+ return jsDateToCalendarDate(/* @__PURE__ */ new Date());
30
+ }
31
+ }
32
+ function stringToCalendarDateTime(str) {
33
+ try {
34
+ return parseDateTime(str);
35
+ } catch {
36
+ return jsDateToCalendarDateTime(/* @__PURE__ */ new Date());
37
+ }
38
+ }
39
+ const hasCustomComponent = computed(() => {
40
+ return props.fieldType?.component !== void 0;
41
+ });
42
+ const customSlotName = computed(() => {
43
+ return props.fieldType?.component ? `field-${props.fieldType.component}` : void 0;
44
+ });
45
+ </script>
46
+
47
+ <template>
48
+ <!-- Custom Component via Slot -->
49
+ <slot
50
+ v-if="hasCustomComponent && customSlotName"
51
+ :name="customSlotName"
52
+ :model-value="modelValue"
53
+ :readonly="readonly"
54
+ :value-type="valueType"
55
+ />
56
+
57
+ <!-- Built-in Input Components -->
58
+ <template v-else>
59
+ <!-- String -->
60
+ <UInput
61
+ v-if="valueType === 'string'"
62
+ :model-value="String(modelValue)"
63
+ size="xs"
64
+ :disabled="readonly"
65
+ placeholder="Enter text..."
66
+ @update:model-value="(val) => modelValue = val"
67
+ />
68
+
69
+ <!-- Textarea (Long Text) -->
70
+ <UTextarea
71
+ v-else-if="valueType === 'textarea'"
72
+ :model-value="String(modelValue)"
73
+ size="xs"
74
+ :disabled="readonly"
75
+ placeholder="Enter long text..."
76
+ :rows="4"
77
+ autoresize
78
+ @update:model-value="(val) => modelValue = val"
79
+ />
80
+
81
+ <!-- Number -->
82
+ <UInputNumber
83
+ v-else-if="valueType === 'number'"
84
+ :model-value="Number(modelValue)"
85
+ size="xs"
86
+ :disabled="readonly"
87
+ placeholder="0"
88
+ @update:model-value="(val) => modelValue = val ?? 0"
89
+ />
90
+
91
+ <!-- Boolean -->
92
+ <USwitch
93
+ v-else-if="valueType === 'boolean'"
94
+ :model-value="Boolean(modelValue)"
95
+ size="xs"
96
+ :disabled="readonly"
97
+ @update:model-value="(val) => modelValue = val"
98
+ />
99
+
100
+ <!-- Date (Date only, no time) -->
101
+ <UInputDate
102
+ v-else-if="valueType === 'date'"
103
+ :model-value="typeof modelValue === 'string' ? stringToCalendarDate(modelValue) : jsDateToCalendarDate(/* @__PURE__ */ new Date())"
104
+ size="xs"
105
+ :disabled="readonly"
106
+ @update:model-value="(val) => {
107
+ if (val && 'year' in val) {
108
+ modelValue = `${val.year}-${String(val.month).padStart(2, '0')}-${String(val.day).padStart(2, '0')}`;
109
+ }
110
+ }"
111
+ />
112
+
113
+ <!-- DateTime (Date + Time) - UInputDate handles both with granularity -->
114
+ <UInputDate
115
+ v-else-if="valueType === 'datetime'"
116
+ :model-value="typeof modelValue === 'string' ? stringToCalendarDateTime(modelValue) : jsDateToCalendarDateTime(/* @__PURE__ */ new Date())"
117
+ size="xs"
118
+ :disabled="readonly"
119
+ granularity="second"
120
+ @update:model-value="(val) => {
121
+ if (val && 'year' in val && 'month' in val && 'day' in val) {
122
+ const hour = 'hour' in val ? val.hour : 0;
123
+ const minute = 'minute' in val ? val.minute : 0;
124
+ const second = 'second' in val ? val.second : 0;
125
+ const newDateTime = new CalendarDateTime(val.year, val.month, val.day, hour, minute, second);
126
+ const isoString = `${newDateTime.year}-${String(newDateTime.month).padStart(2, '0')}-${String(newDateTime.day).padStart(2, '0')}T${String(newDateTime.hour).padStart(2, '0')}:${String(newDateTime.minute).padStart(2, '0')}:${String(newDateTime.second).padStart(2, '0')}`;
127
+ modelValue = isoString;
128
+ }
129
+ }"
130
+ />
131
+
132
+ <!-- String Array (Tags) -->
133
+ <UInputTags
134
+ v-else-if="valueType === 'string-array'"
135
+ :model-value="Array.isArray(modelValue) ? modelValue : []"
136
+ size="xs"
137
+ :disabled="readonly"
138
+ placeholder="Add tags..."
139
+ @update:model-value="(val) => modelValue = val"
140
+ />
141
+
142
+ <!-- Null -->
143
+ <div v-else-if="valueType === 'null'" class="text-xs text-muted italic">
144
+ null
145
+ </div>
146
+
147
+ <!-- Fallback for unknown types -->
148
+ <UInput
149
+ v-else
150
+ :model-value="String(modelValue || '')"
151
+ size="xs"
152
+ :disabled="readonly"
153
+ placeholder="Enter value..."
154
+ @update:model-value="(val) => modelValue = val"
155
+ />
156
+ </template>
157
+ </template>
@@ -0,0 +1,37 @@
1
+ import type { YamlFieldType } from "../types/types.js";
2
+ type YamlValue = string | number | boolean | null | Date | YamlValue[] | {
3
+ [key: string]: YamlValue;
4
+ };
5
+ type __VLS_Props = {
6
+ /** Type of the field (string, number, boolean, etc.) */
7
+ valueType: string;
8
+ /** Whether the field is read-only */
9
+ readonly?: boolean;
10
+ /** Optional field type definition for custom component detection */
11
+ fieldType?: YamlFieldType;
12
+ };
13
+ type __VLS_ModelProps = {
14
+ modelValue: YamlValue;
15
+ };
16
+ type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
17
+ declare var __VLS_2: any, __VLS_3: {
18
+ modelValue: YamlValue;
19
+ readonly: boolean;
20
+ valueType: string;
21
+ };
22
+ type __VLS_Slots = {} & {
23
+ [K in NonNullable<typeof __VLS_2>]?: (props: typeof __VLS_3) => any;
24
+ };
25
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
26
+ "update:modelValue": (value: YamlValue) => any;
27
+ }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
28
+ "onUpdate:modelValue"?: ((value: YamlValue) => any) | undefined;
29
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
30
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
31
+ declare const _default: typeof __VLS_export;
32
+ export default _default;
33
+ type __VLS_WithSlots<T, S> = T & {
34
+ new (): {
35
+ $slots: S;
36
+ };
37
+ };
@@ -0,0 +1,92 @@
1
+ /**
2
+ * YAML Form Data Editor
3
+ *
4
+ * Schema-driven form editor for YAML/frontmatter data.
5
+ * Supports custom field types through the fieldTypes prop.
6
+ *
7
+ * Features:
8
+ * - Primitive types (string, number, boolean, null)
9
+ * - Complex types (date, datetime, string-array)
10
+ * - Objects (nested structures)
11
+ * - Arrays (primitives and objects)
12
+ * - Recursive structures
13
+ * - Custom field types with custom components
14
+ *
15
+ * Can be used standalone or embedded in the rich text editor for frontmatter editing.
16
+ */
17
+ import type { YamlFieldType, YamlFormData } from "../types/types.js";
18
+ type __VLS_Props = {
19
+ filePath?: string;
20
+ readonly?: boolean;
21
+ /** Custom field type definitions (merged with defaults) */
22
+ fieldTypes?: YamlFieldType[];
23
+ };
24
+ type __VLS_ModelProps = {
25
+ modelValue: YamlFormData;
26
+ };
27
+ type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
28
+ declare var __VLS_12: string, __VLS_13: {
29
+ modelValue: string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | /*elided*/ any | {
30
+ [key: string]: string | number | boolean | Date | /*elided*/ any | /*elided*/ any | null;
31
+ } | null)[] | {
32
+ [key: string]: string | number | boolean | Date | (string | number | boolean | Date | /*elided*/ any | /*elided*/ any | null)[] | /*elided*/ any | null;
33
+ } | null)[] | {
34
+ [key: string]: string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | /*elided*/ any | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null;
35
+ } | null)[] | {
36
+ [key: string]: string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | /*elided*/ any | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null;
37
+ } | null)[] | {
38
+ [key: string]: string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | /*elided*/ any | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null;
39
+ } | null)[] | {
40
+ [key: string]: string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | /*elided*/ any | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null;
41
+ } | null)[] | {
42
+ [key: string]: string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | /*elided*/ any | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null;
43
+ } | null)[] | {
44
+ [key: string]: string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | /*elided*/ any | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null;
45
+ } | null)[] | {
46
+ [key: string]: string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | /*elided*/ any | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null;
47
+ } | null)[] | {
48
+ [key: string]: string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | /*elided*/ any | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null;
49
+ } | null)[] | {
50
+ [key: string]: string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | /*elided*/ any | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null;
51
+ } | null)[] | {
52
+ [key: string]: string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | /*elided*/ any | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null;
53
+ } | null;
54
+ readonly: boolean;
55
+ valueType: string;
56
+ };
57
+ type __VLS_Slots = {} & {
58
+ [K in NonNullable<typeof __VLS_12>]?: (props: typeof __VLS_13) => any;
59
+ };
60
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
61
+ "update:modelValue": (value: {
62
+ [key: string]: any;
63
+ title?: string;
64
+ description?: string;
65
+ date?: Date;
66
+ draft?: boolean;
67
+ tags?: string[];
68
+ categories?: string[];
69
+ image?: string;
70
+ slug?: string;
71
+ }) => any;
72
+ }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
73
+ "onUpdate:modelValue"?: ((value: {
74
+ [key: string]: any;
75
+ title?: string;
76
+ description?: string;
77
+ date?: Date;
78
+ draft?: boolean;
79
+ tags?: string[];
80
+ categories?: string[];
81
+ image?: string;
82
+ slug?: string;
83
+ }) => any) | undefined;
84
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
85
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
86
+ declare const _default: typeof __VLS_export;
87
+ export default _default;
88
+ type __VLS_WithSlots<T, S> = T & {
89
+ new (): {
90
+ $slots: S;
91
+ };
92
+ };
@@ -0,0 +1,68 @@
1
+ <script setup>
2
+ import { useYamlFieldTypes } from "../composables/useYamlFieldTypes";
3
+ import YamlFormField from "../components/YamlFormField.vue";
4
+ const data = defineModel({ type: null, ...{ required: true } });
5
+ const props = defineProps({
6
+ filePath: { type: String, required: false },
7
+ readonly: { type: Boolean, required: false, default: false },
8
+ fieldTypes: { type: Array, required: false }
9
+ });
10
+ const { getDefaultValue, getTypeMenuItems } = useYamlFieldTypes(props.fieldTypes);
11
+ const isDirty = ref(false);
12
+ watch(data, () => {
13
+ isDirty.value = true;
14
+ }, { deep: true });
15
+ function addField(fieldType = "string") {
16
+ if (!data.value) data.value = {};
17
+ const newKey = `field_${Object.keys(data.value).length + 1}`;
18
+ data.value[newKey] = getDefaultValue(fieldType);
19
+ }
20
+ function removeField(key) {
21
+ if (data.value) {
22
+ delete data.value[key];
23
+ }
24
+ }
25
+ const addFieldOptions = computed(() => {
26
+ return getTypeMenuItems((type) => addField(type));
27
+ });
28
+ </script>
29
+
30
+ <template>
31
+ <div class="space-y-4">
32
+ <div class="space-y-3">
33
+ <YamlFormField
34
+ v-for="(value, key) in data"
35
+ :key="String(key)"
36
+ v-model="data[key]"
37
+ :field-key="String(key)"
38
+ :readonly="readonly"
39
+ :field-types="fieldTypes"
40
+ @remove="removeField(String(key))"
41
+ @update:field-key="(newKey) => {
42
+ if (newKey !== key) {
43
+ data[newKey] = data[key];
44
+ delete data[key];
45
+ }
46
+ }"
47
+ >
48
+ <!-- Forward all slots to YamlFormField for custom field components -->
49
+ <template v-for="(_, name) in $slots" #[name]="slotProps">
50
+ <slot :name="name" v-bind="slotProps" />
51
+ </template>
52
+ </YamlFormField>
53
+ </div>
54
+
55
+ <UDropdownMenu
56
+ v-if="!readonly"
57
+ :items="[addFieldOptions]"
58
+ size="sm"
59
+ >
60
+ <UButton
61
+ icon="i-lucide-plus"
62
+ label="Add Field"
63
+ variant="ghost"
64
+ size="sm"
65
+ />
66
+ </UDropdownMenu>
67
+ </div>
68
+ </template>
@@ -0,0 +1,92 @@
1
+ /**
2
+ * YAML Form Data Editor
3
+ *
4
+ * Schema-driven form editor for YAML/frontmatter data.
5
+ * Supports custom field types through the fieldTypes prop.
6
+ *
7
+ * Features:
8
+ * - Primitive types (string, number, boolean, null)
9
+ * - Complex types (date, datetime, string-array)
10
+ * - Objects (nested structures)
11
+ * - Arrays (primitives and objects)
12
+ * - Recursive structures
13
+ * - Custom field types with custom components
14
+ *
15
+ * Can be used standalone or embedded in the rich text editor for frontmatter editing.
16
+ */
17
+ import type { YamlFieldType, YamlFormData } from "../types/types.js";
18
+ type __VLS_Props = {
19
+ filePath?: string;
20
+ readonly?: boolean;
21
+ /** Custom field type definitions (merged with defaults) */
22
+ fieldTypes?: YamlFieldType[];
23
+ };
24
+ type __VLS_ModelProps = {
25
+ modelValue: YamlFormData;
26
+ };
27
+ type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
28
+ declare var __VLS_12: string, __VLS_13: {
29
+ modelValue: string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | /*elided*/ any | {
30
+ [key: string]: string | number | boolean | Date | /*elided*/ any | /*elided*/ any | null;
31
+ } | null)[] | {
32
+ [key: string]: string | number | boolean | Date | (string | number | boolean | Date | /*elided*/ any | /*elided*/ any | null)[] | /*elided*/ any | null;
33
+ } | null)[] | {
34
+ [key: string]: string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | /*elided*/ any | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null;
35
+ } | null)[] | {
36
+ [key: string]: string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | /*elided*/ any | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null;
37
+ } | null)[] | {
38
+ [key: string]: string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | /*elided*/ any | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null;
39
+ } | null)[] | {
40
+ [key: string]: string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | /*elided*/ any | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null;
41
+ } | null)[] | {
42
+ [key: string]: string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | /*elided*/ any | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null;
43
+ } | null)[] | {
44
+ [key: string]: string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | /*elided*/ any | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null;
45
+ } | null)[] | {
46
+ [key: string]: string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | /*elided*/ any | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null;
47
+ } | null)[] | {
48
+ [key: string]: string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | /*elided*/ any | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null;
49
+ } | null)[] | {
50
+ [key: string]: string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | /*elided*/ any | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null;
51
+ } | null)[] | {
52
+ [key: string]: string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | (string | number | boolean | Date | /*elided*/ any | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null)[] | /*elided*/ any | null;
53
+ } | null;
54
+ readonly: boolean;
55
+ valueType: string;
56
+ };
57
+ type __VLS_Slots = {} & {
58
+ [K in NonNullable<typeof __VLS_12>]?: (props: typeof __VLS_13) => any;
59
+ };
60
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
61
+ "update:modelValue": (value: {
62
+ [key: string]: any;
63
+ title?: string;
64
+ description?: string;
65
+ date?: Date;
66
+ draft?: boolean;
67
+ tags?: string[];
68
+ categories?: string[];
69
+ image?: string;
70
+ slug?: string;
71
+ }) => any;
72
+ }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
73
+ "onUpdate:modelValue"?: ((value: {
74
+ [key: string]: any;
75
+ title?: string;
76
+ description?: string;
77
+ date?: Date;
78
+ draft?: boolean;
79
+ tags?: string[];
80
+ categories?: string[];
81
+ image?: string;
82
+ slug?: string;
83
+ }) => any) | undefined;
84
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
85
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
86
+ declare const _default: typeof __VLS_export;
87
+ export default _default;
88
+ type __VLS_WithSlots<T, S> = T & {
89
+ new (): {
90
+ $slots: S;
91
+ };
92
+ };