mktcms 0.2.16 → 0.3.1

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 (26) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/module.mjs +2 -1
  3. package/dist/runtime/app/components/content/editor/{selectFile/index.vue.d.ts → frontmatter/filePicker/modal.d.vue.ts} +3 -2
  4. package/dist/runtime/app/components/content/editor/frontmatter/filePicker/modal.vue +122 -0
  5. package/dist/runtime/app/components/content/editor/{selectFile/index.d.vue.ts → frontmatter/filePicker/modal.vue.d.ts} +3 -2
  6. package/dist/runtime/app/components/content/editor/{selectFile/breadcrumb.d.vue.ts → frontmatter/filePicker/node.d.vue.ts} +5 -2
  7. package/dist/runtime/app/components/content/editor/frontmatter/filePicker/node.vue +145 -0
  8. package/dist/runtime/app/components/content/editor/{selectFile/breadcrumb.vue.d.ts → frontmatter/filePicker/node.vue.d.ts} +5 -2
  9. package/dist/runtime/app/components/content/editor/frontmatter/form.d.vue.ts +1 -2
  10. package/dist/runtime/app/components/content/editor/frontmatter/form.vue +175 -193
  11. package/dist/runtime/app/components/content/editor/frontmatter/form.vue.d.ts +1 -2
  12. package/dist/runtime/app/components/content/editor/frontmatter/input.d.vue.ts +4 -0
  13. package/dist/runtime/app/components/content/editor/frontmatter/input.vue +41 -30
  14. package/dist/runtime/app/components/content/editor/frontmatter/input.vue.d.ts +4 -0
  15. package/dist/runtime/app/components/content/editor/frontmatter/modal.d.vue.ts +1 -0
  16. package/dist/runtime/app/components/content/editor/frontmatter/modal.vue +17 -87
  17. package/dist/runtime/app/components/content/editor/frontmatter/modal.vue.d.ts +1 -0
  18. package/dist/runtime/app/components/content/editor/markdown.vue +3 -1
  19. package/dist/runtime/app/styles/admin.css +1 -1
  20. package/dist/runtime/app/styles/admin.min.css +1 -1
  21. package/dist/runtime/server/api/admin/list.js +13 -5
  22. package/dist/runtime/server/api/admin/md.d.ts +1 -0
  23. package/dist/runtime/server/api/admin/md.js +14 -2
  24. package/package.json +2 -1
  25. package/dist/runtime/app/components/content/editor/selectFile/breadcrumb.vue +0 -51
  26. package/dist/runtime/app/components/content/editor/selectFile/index.vue +0 -89
@@ -1,86 +1,155 @@
1
1
  <script setup>
2
- import { reactive } from "vue";
2
+ import { computed, watch } from "vue";
3
3
  import FrontmatterInput from "./input.vue";
4
4
  defineOptions({
5
5
  name: "FrontmatterForm"
6
6
  });
7
7
  const props = defineProps({
8
- label: { type: String, required: false, default: "" },
9
- depth: { type: Number, required: false, default: 0 }
8
+ depth: { type: Number, required: false, default: 0 },
9
+ schema: { type: [Object, null], required: true }
10
10
  });
11
11
  const frontmatter = defineModel("frontmatter", { type: null, ...{
12
12
  required: true
13
13
  } });
14
- const openState = reactive({});
15
- function isBoolean(value) {
16
- return typeof value === "boolean";
14
+ function isRecord(value) {
15
+ return typeof value === "object" && value !== null && !Array.isArray(value);
17
16
  }
18
- function isNumber(value) {
19
- return typeof value === "number";
17
+ function isBooleanSchema(schema) {
18
+ return isRecord(schema) && schema.type === "boolean";
20
19
  }
21
20
  function isObject(value) {
22
- return typeof value === "object" && value !== null && !Array.isArray(value);
21
+ return isRecord(value);
22
+ }
23
+ function isArraySchema(schema) {
24
+ return isRecord(schema) && schema.type === "array";
25
+ }
26
+ function isObjectSchema(schema) {
27
+ return isRecord(schema) && schema.type === "object";
23
28
  }
24
- function arrayItemLabel(index) {
25
- return `Element ${index + 1}`;
29
+ function isPrimitiveSchema(schema) {
30
+ return isRecord(schema) && ["string", "number", "date", "datetime"].includes(schema.type ?? "");
26
31
  }
27
- function objectKeys(value) {
28
- return Object.keys(value);
32
+ function isSchemaMap(schema) {
33
+ return isRecord(schema) && !("type" in schema);
29
34
  }
30
- function createEmptyLike(value) {
31
- if (Array.isArray(value)) {
35
+ function schemaEntries(schema) {
36
+ return Object.entries(schema);
37
+ }
38
+ function createDefaultFromSchema(schema) {
39
+ if (!schema || !schema.type) {
40
+ return "";
41
+ }
42
+ if (schema.type === "array") {
32
43
  return [];
33
44
  }
34
- if (isObject(value)) {
45
+ if (schema.type === "object") {
35
46
  const next = {};
36
- for (const key of Object.keys(value)) {
37
- next[key] = createEmptyLike(value[key]);
47
+ const properties = schema.properties ?? {};
48
+ for (const key of Object.keys(properties)) {
49
+ next[key] = createDefaultFromSchema(properties[key]);
38
50
  }
39
51
  return next;
40
52
  }
41
- if (isBoolean(value)) {
53
+ if (schema.type === "boolean") {
42
54
  return false;
43
55
  }
44
- if (isNumber(value)) {
56
+ if (schema.type === "number") {
45
57
  return 0;
46
58
  }
47
59
  return "";
48
60
  }
49
- function addArrayItem(arrayRef) {
50
- if (arrayRef.length === 0) {
51
- arrayRef.push("");
61
+ function ensureInitializedFromSchema() {
62
+ const schema = props.schema;
63
+ if (!schema) {
52
64
  return;
53
65
  }
54
- const lastItem = arrayRef[arrayRef.length - 1];
55
- arrayRef.push(createEmptyLike(lastItem));
56
- }
57
- function removeArrayItem(arrayRef, index) {
58
- if (arrayRef.length <= 1) {
66
+ if (isSchemaMap(schema)) {
67
+ if (!isObject(frontmatter.value)) {
68
+ frontmatter.value = {};
69
+ }
70
+ for (const [key, fieldSchema] of schemaEntries(schema)) {
71
+ if (frontmatter.value[key] === void 0) {
72
+ frontmatter.value[key] = createDefaultFromSchema(fieldSchema);
73
+ }
74
+ }
59
75
  return;
60
76
  }
61
- arrayRef.splice(index, 1);
62
- }
63
- function moveArrayItem(arrayRef, from, to) {
64
- if (to < 0 || to >= arrayRef.length || from === to) {
77
+ if (isObjectSchema(schema)) {
78
+ if (!isObject(frontmatter.value)) {
79
+ frontmatter.value = {};
80
+ }
81
+ const properties = schema.properties ?? {};
82
+ for (const [key, fieldSchema] of schemaEntries(properties)) {
83
+ if (frontmatter.value[key] === void 0) {
84
+ frontmatter.value[key] = createDefaultFromSchema(fieldSchema);
85
+ }
86
+ }
65
87
  return;
66
88
  }
67
- const [item] = arrayRef.splice(from, 1);
68
- arrayRef.splice(to, 0, item);
89
+ if (isArraySchema(schema) && !Array.isArray(frontmatter.value)) {
90
+ frontmatter.value = [];
91
+ }
69
92
  }
70
- function arrayItemStateKey(index) {
71
- return `array-${index}`;
93
+ watch(
94
+ () => props.schema,
95
+ () => {
96
+ ensureInitializedFromSchema();
97
+ },
98
+ { immediate: true, deep: true }
99
+ );
100
+ const objectSchemaEntries = computed(() => {
101
+ if (!props.schema) {
102
+ return [];
103
+ }
104
+ if (isSchemaMap(props.schema)) {
105
+ return schemaEntries(props.schema);
106
+ }
107
+ if (isObjectSchema(props.schema)) {
108
+ return schemaEntries(props.schema.properties ?? {});
109
+ }
110
+ return [];
111
+ });
112
+ const arrayItemSchema = computed(() => {
113
+ if (!props.schema || !isArraySchema(props.schema)) {
114
+ return null;
115
+ }
116
+ return props.schema.items ?? null;
117
+ });
118
+ function addArrayItem(arrayRef, itemSchema) {
119
+ arrayRef.push(createDefaultFromSchema(itemSchema));
72
120
  }
73
- function objectItemStateKey(key) {
74
- return `object-${key}`;
121
+ function getFieldLabel(key, fieldSchema) {
122
+ return fieldSchema.label || key;
75
123
  }
76
- function isOpen(key) {
77
- if (typeof openState[key] === "undefined") {
78
- openState[key] = false;
124
+ function getInputTypeFromSchema(schema) {
125
+ if (!schema || !schema.type) {
126
+ return "text";
127
+ }
128
+ if (schema.type === "number") {
129
+ return "number";
79
130
  }
80
- return openState[key];
131
+ if (schema.type === "date") {
132
+ return "date";
133
+ }
134
+ if (schema.type === "datetime") {
135
+ return "datetime-local";
136
+ }
137
+ return "text";
81
138
  }
82
- function toggleOpen(key) {
83
- openState[key] = !isOpen(key);
139
+ function getUiHintFromSchema(schema) {
140
+ if (!schema || schema.type !== "string") {
141
+ return void 0;
142
+ }
143
+ if (schema["x-ui"] === "image" || schema["x-ui"] === "pdf" || schema["x-ui"] === "file") {
144
+ return schema["x-ui"];
145
+ }
146
+ return void 0;
147
+ }
148
+ function removeArrayItem(arrayRef, index) {
149
+ if (arrayRef.length <= 1) {
150
+ return;
151
+ }
152
+ arrayRef.splice(index, 1);
84
153
  }
85
154
  </script>
86
155
 
@@ -96,86 +165,24 @@ function toggleOpen(key) {
96
165
  'bg-gray-100/90': props.depth >= 5
97
166
  }"
98
167
  >
99
- <p
100
- v-if="props.label"
101
- class="font-bold text-[15px]"
102
- >
103
- {{ props.label }}
104
- </p>
105
-
106
- <template v-if="Array.isArray(frontmatter)">
168
+ <template v-if="props.schema && isArraySchema(props.schema) && Array.isArray(frontmatter)">
107
169
  <div
108
170
  v-for="(item, index) in frontmatter"
109
171
  :key="index"
110
- class="flex flex-col gap-0 border border-gray-200 rounded-sm bg-white/50 overflow-hidden"
172
+ class="flex flex-col gap-2"
111
173
  >
112
- <div class="flex items-center justify-between gap-2 px-3 py-2">
174
+ <div class="flex items-center justify-end gap-2">
113
175
  <button
114
- v-if="!isBoolean(item)"
115
176
  type="button"
116
- class="flex-1 flex items-center gap-2 min-w-0 text-left rounded-sm px-2 py-1 transition-colors duration-200 hover:bg-gray-200/70 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-gray-300"
117
- :aria-expanded="isOpen(arrayItemStateKey(index))"
118
- @click="toggleOpen(arrayItemStateKey(index))"
177
+ class="button secondary small"
178
+ :disabled="frontmatter.length <= 1"
179
+ @click="removeArrayItem(frontmatter, index)"
119
180
  >
120
- <svg
121
- xmlns="http://www.w3.org/2000/svg"
122
- fill="none"
123
- viewBox="0 0 24 24"
124
- stroke-width="1.5"
125
- stroke="currentColor"
126
- class="size-4 transition-transform duration-300"
127
- :class="{ 'rotate-180': isOpen(arrayItemStateKey(index)) }"
128
- >
129
- <path
130
- stroke-linecap="round"
131
- stroke-linejoin="round"
132
- d="m19.5 8.25-7.5 7.5-7.5-7.5"
133
- />
134
- </svg>
135
- <span class="font-bold text-sm">{{ arrayItemLabel(index) }}</span>
181
+ Entfernen
136
182
  </button>
137
-
138
- <div
139
- v-else
140
- class="flex-1 min-w-0 px-2 py-1"
141
- >
142
- <span class="font-bold text-sm">{{ arrayItemLabel(index) }}</span>
143
- </div>
144
-
145
- <div class="flex items-center gap-1">
146
- <button
147
- type="button"
148
- class="button secondary small"
149
- :disabled="index === 0"
150
- @click="moveArrayItem(frontmatter, index, index - 1)"
151
- >
152
-
153
- </button>
154
-
155
- <button
156
- type="button"
157
- class="button secondary small"
158
- :disabled="index === frontmatter.length - 1"
159
- @click="moveArrayItem(frontmatter, index, index + 1)"
160
- >
161
-
162
- </button>
163
-
164
- <button
165
- type="button"
166
- class="button secondary small"
167
- :disabled="frontmatter.length <= 1"
168
- @click="removeArrayItem(frontmatter, index)"
169
- >
170
- Entfernen
171
- </button>
172
- </div>
173
183
  </div>
174
184
 
175
- <div
176
- v-if="isBoolean(item)"
177
- class="px-3 pb-3"
178
- >
185
+ <div v-if="isBooleanSchema(arrayItemSchema)">
179
186
  <label class="inline-flex items-center">
180
187
  <input
181
188
  v-model="frontmatter[index]"
@@ -185,110 +192,85 @@ function toggleOpen(key) {
185
192
  </label>
186
193
  </div>
187
194
 
188
- <div
189
- v-else
190
- class="grid transition-[grid-template-rows] duration-300 ease-in-out"
191
- :class="isOpen(arrayItemStateKey(index)) ? 'grid-rows-[1fr] mt-2' : 'grid-rows-[0fr]'"
192
- >
193
- <div class="overflow-hidden px-3 pb-3">
194
- <FrontmatterInput
195
- v-if="typeof item === 'string' || isNumber(item)"
196
- v-model:value="frontmatter[index]"
197
- label=""
198
- />
195
+ <FrontmatterInput
196
+ v-else-if="isPrimitiveSchema(arrayItemSchema)"
197
+ v-model:value="frontmatter[index]"
198
+ label=""
199
+ :input-type="getInputTypeFromSchema(arrayItemSchema)"
200
+ :ui-hint="getUiHintFromSchema(arrayItemSchema)"
201
+ />
199
202
 
200
- <FrontmatterForm
201
- v-else-if="isObject(item) || Array.isArray(item)"
202
- v-model:frontmatter="frontmatter[index]"
203
- label=""
204
- :depth="props.depth + 1"
205
- />
203
+ <FrontmatterForm
204
+ v-else-if="isObjectSchema(arrayItemSchema) || isArraySchema(arrayItemSchema)"
205
+ v-model:frontmatter="frontmatter[index]"
206
+ :schema="arrayItemSchema"
207
+ :depth="props.depth + 1"
208
+ />
206
209
 
207
- <FrontmatterInput
208
- v-else
209
- v-model:value="frontmatter[index]"
210
- label=""
211
- />
212
- </div>
213
- </div>
210
+ <FrontmatterInput
211
+ v-else
212
+ v-model:value="frontmatter[index]"
213
+ label=""
214
+ />
214
215
  </div>
215
216
 
216
217
  <button
217
218
  type="button"
218
219
  class="button secondary small self-start"
219
- @click="addArrayItem(frontmatter)"
220
+ @click="addArrayItem(frontmatter, arrayItemSchema)"
220
221
  >
221
222
  Element hinzufügen
222
223
  </button>
223
224
  </template>
224
225
 
225
- <template v-else>
226
+ <template v-else-if="objectSchemaEntries.length > 0 && isObject(frontmatter)">
226
227
  <div
227
- v-for="key in objectKeys(frontmatter)"
228
- :key="key"
229
- class="flex flex-col gap-0 border border-gray-200 rounded-sm bg-white/45 overflow-hidden"
228
+ v-for="entry in objectSchemaEntries"
229
+ :key="entry[0]"
230
+ class="flex flex-col gap-1"
230
231
  >
231
232
  <label
232
- v-if="isBoolean(frontmatter[key])"
233
- class="w-full inline-flex items-center px-3 py-2 font-bold text-sm"
233
+ v-if="isBooleanSchema(entry[1])"
234
+ class="w-full inline-flex items-center font-bold text-sm"
234
235
  >
235
236
  <input
236
- v-model="frontmatter[key]"
237
+ v-model="frontmatter[entry[0]]"
237
238
  type="checkbox"
238
239
  class="mr-2"
239
240
  >
240
- <span>{{ key }}</span>
241
+ <span>{{ getFieldLabel(entry[0], entry[1]) }}</span>
241
242
  </label>
242
243
 
243
- <button
244
- v-else
245
- type="button"
246
- class="w-full flex items-center gap-2 min-w-0 text-left px-3 py-2 transition-colors duration-200 hover:bg-gray-200/70 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-gray-300"
247
- :aria-expanded="isOpen(objectItemStateKey(key))"
248
- @click="toggleOpen(objectItemStateKey(key))"
249
- >
250
- <svg
251
- xmlns="http://www.w3.org/2000/svg"
252
- fill="none"
253
- viewBox="0 0 24 24"
254
- stroke-width="1.5"
255
- stroke="currentColor"
256
- class="size-4 transition-transform duration-300"
257
- :class="{ 'rotate-180': isOpen(objectItemStateKey(key)) }"
258
- >
259
- <path
260
- stroke-linecap="round"
261
- stroke-linejoin="round"
262
- d="m19.5 8.25-7.5 7.5-7.5-7.5"
263
- />
264
- </svg>
265
- <span class="font-bold text-sm">{{ key }}</span>
266
- </button>
244
+ <template v-else>
245
+ <p class="font-bold text-sm">
246
+ {{ getFieldLabel(entry[0], entry[1]) }}
247
+ </p>
267
248
 
268
- <div
269
- v-if="!isBoolean(frontmatter[key])"
270
- class="grid transition-[grid-template-rows] duration-300 ease-in-out"
271
- :class="isOpen(objectItemStateKey(key)) ? 'grid-rows-[1fr] mt-2' : 'grid-rows-[0fr]'"
272
- >
273
- <div class="overflow-hidden px-3 pb-3">
274
- <FrontmatterInput
275
- v-if="typeof frontmatter[key] === 'string' || isNumber(frontmatter[key])"
276
- v-model:value="frontmatter[key]"
277
- />
249
+ <FrontmatterInput
250
+ v-if="isPrimitiveSchema(entry[1])"
251
+ v-model:value="frontmatter[entry[0]]"
252
+ :input-type="getInputTypeFromSchema(entry[1])"
253
+ :ui-hint="getUiHintFromSchema(entry[1])"
254
+ />
278
255
 
279
- <FrontmatterForm
280
- v-else-if="isObject(frontmatter[key]) || Array.isArray(frontmatter[key])"
281
- v-model:frontmatter="frontmatter[key]"
282
- label=""
283
- :depth="props.depth + 1"
284
- />
256
+ <FrontmatterForm
257
+ v-else-if="isObjectSchema(entry[1]) || isArraySchema(entry[1])"
258
+ v-model:frontmatter="frontmatter[entry[0]]"
259
+ :schema="entry[1]"
260
+ :depth="props.depth + 1"
261
+ />
285
262
 
286
- <FrontmatterInput
287
- v-else
288
- v-model:value="frontmatter[key]"
289
- />
290
- </div>
291
- </div>
263
+ <FrontmatterInput
264
+ v-else
265
+ v-model:value="frontmatter[entry[0]]"
266
+ />
267
+ </template>
268
+ </div>
269
+ </template>
270
+
271
+ <template v-else>
272
+ <div class="text-sm text-gray-600">
273
+ Keine Felder in der Frontmatter-Konfiguration vorhanden.
292
274
  </div>
293
275
  </template>
294
276
  </div>
@@ -1,6 +1,6 @@
1
1
  type __VLS_Props = {
2
- label?: string;
3
2
  depth?: number;
3
+ schema: Record<string, any> | null;
4
4
  };
5
5
  type __VLS_ModelProps = {
6
6
  'frontmatter': any;
@@ -11,7 +11,6 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
11
11
  }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
12
12
  "onUpdate:frontmatter"?: ((value: any) => any) | undefined;
13
13
  }>, {
14
- label: string;
15
14
  depth: number;
16
15
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
17
16
  declare const _default: typeof __VLS_export;
@@ -1,5 +1,7 @@
1
1
  type __VLS_Props = {
2
2
  label?: string;
3
+ inputType?: 'text' | 'number' | 'date' | 'datetime-local';
4
+ uiHint?: 'image' | 'pdf' | 'file';
3
5
  };
4
6
  type __VLS_ModelProps = {
5
7
  'value': string | number;
@@ -11,6 +13,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
11
13
  "onUpdate:value"?: ((value: string | number) => any) | undefined;
12
14
  }>, {
13
15
  label: string;
16
+ uiHint: "image" | "pdf" | "file";
17
+ inputType: "text" | "number" | "date" | "datetime-local";
14
18
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
15
19
  declare const _default: typeof __VLS_export;
16
20
  export default _default;
@@ -1,13 +1,22 @@
1
1
  <script setup>
2
2
  import { computed, ref } from "vue";
3
- import SelectFile from "../selectFile/index.vue";
3
+ import FilePickerModal from "./filePicker/modal.vue";
4
4
  const props = defineProps({
5
- label: { type: String, required: false, default: "" }
5
+ label: { type: String, required: false, default: "" },
6
+ inputType: { type: String, required: false, default: "text" },
7
+ uiHint: { type: String, required: false, default: void 0 }
6
8
  });
7
9
  const value = defineModel("value", { type: [String, Number], ...{
8
10
  required: true
9
11
  } });
10
- const isNumberInput = computed(() => typeof value.value === "number");
12
+ const isPickerOpen = ref(false);
13
+ const resolvedInputType = computed(() => {
14
+ if (props.inputType !== "text") {
15
+ return props.inputType;
16
+ }
17
+ return typeof value.value === "number" ? "number" : "text";
18
+ });
19
+ const isNumberInput = computed(() => resolvedInputType.value === "number");
11
20
  const inputValue = computed({
12
21
  get() {
13
22
  return `${value.value ?? ""}`;
@@ -21,7 +30,21 @@ const inputValue = computed({
21
30
  value.value = newValue;
22
31
  }
23
32
  });
24
- const showFileSelect = ref(false);
33
+ const pickerButtonLabel = computed(() => {
34
+ if (props.uiHint === "image") {
35
+ return "Bild ausw\xE4hlen";
36
+ }
37
+ if (props.uiHint === "pdf") {
38
+ return "PDF ausw\xE4hlen";
39
+ }
40
+ if (props.uiHint === "file") {
41
+ return "Datei ausw\xE4hlen";
42
+ }
43
+ return "";
44
+ });
45
+ function onPickerSelect(path) {
46
+ value.value = path;
47
+ }
25
48
  </script>
26
49
 
27
50
  <template>
@@ -32,41 +55,29 @@ const showFileSelect = ref(false);
32
55
  >
33
56
  {{ props.label }}
34
57
  </label>
35
- <div class="relative">
58
+ <div class="flex items-center gap-2">
36
59
  <input
37
60
  v-model="inputValue"
38
- :type="isNumberInput ? 'number' : 'text'"
61
+ :type="resolvedInputType"
39
62
  class="w-full"
40
63
  >
64
+
41
65
  <button
42
- v-if="!isNumberInput"
66
+ v-if="props.uiHint"
43
67
  type="button"
44
- class="absolute top-1/2 right-2 -translate-y-1/2 button secondary small"
45
- @click="showFileSelect = true"
68
+ class="button secondary small whitespace-nowrap"
69
+ @click="isPickerOpen = true"
46
70
  >
47
- <svg
48
- xmlns="http://www.w3.org/2000/svg"
49
- fill="none"
50
- viewBox="0 0 24 24"
51
- stroke-width="1.5"
52
- stroke="currentColor"
53
- class="size-5"
54
- >
55
- <path
56
- stroke-linecap="round"
57
- stroke-linejoin="round"
58
- d="m2.25 15.75 5.159-5.159a2.25 2.25 0 0 1 3.182 0l5.159 5.159m-1.5-1.5 1.409-1.409a2.25 2.25 0 0 1 3.182 0l2.909 2.909m-18 3.75h16.5a1.5 1.5 0 0 0 1.5-1.5V6a1.5 1.5 0 0 0-1.5-1.5H3.75A1.5 1.5 0 0 0 2.25 6v12a1.5 1.5 0 0 0 1.5 1.5Zm10.5-11.25h.008v.008h-.008V8.25Zm.375 0a.375.375 0 1 1-.75 0 .375.375 0 0 1 .75 0Z"
59
- />
60
- </svg>
71
+ {{ pickerButtonLabel }}
61
72
  </button>
62
73
  </div>
63
- <SelectFile
64
- v-if="!isNumberInput"
65
- :is-open="showFileSelect"
66
- @close="showFileSelect = false"
67
- @select="(filePath) => {
68
- value = filePath;
69
- }"
74
+
75
+ <FilePickerModal
76
+ v-if="props.uiHint"
77
+ :is-open="isPickerOpen"
78
+ :ui-hint="props.uiHint"
79
+ @close="isPickerOpen = false"
80
+ @select="onPickerSelect"
70
81
  />
71
82
  </div>
72
83
  </template>
@@ -1,5 +1,7 @@
1
1
  type __VLS_Props = {
2
2
  label?: string;
3
+ inputType?: 'text' | 'number' | 'date' | 'datetime-local';
4
+ uiHint?: 'image' | 'pdf' | 'file';
3
5
  };
4
6
  type __VLS_ModelProps = {
5
7
  'value': string | number;
@@ -11,6 +13,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
11
13
  "onUpdate:value"?: ((value: string | number) => any) | undefined;
12
14
  }>, {
13
15
  label: string;
16
+ uiHint: "image" | "pdf" | "file";
17
+ inputType: "text" | "number" | "date" | "datetime-local";
14
18
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
15
19
  declare const _default: typeof __VLS_export;
16
20
  export default _default;
@@ -1,5 +1,6 @@
1
1
  type __VLS_Props = {
2
2
  isOpen: boolean;
3
+ schema: Record<string, any> | null;
3
4
  };
4
5
  type __VLS_ModelProps = {
5
6
  'frontmatter': any;