rimelight-components 2.0.49 → 2.0.50
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/module.json +1 -1
- package/dist/module.mjs +1 -1
- package/dist/runtime/components/blocks/BlockEditor.d.vue.ts +6 -2
- package/dist/runtime/components/blocks/BlockEditor.vue +4 -64
- package/dist/runtime/components/blocks/BlockEditor.vue.d.ts +6 -2
- package/dist/runtime/components/page/PageEditor.d.vue.ts +24 -0
- package/dist/runtime/components/page/PageEditor.vue +102 -0
- package/dist/runtime/components/page/PageEditor.vue.d.ts +24 -0
- package/dist/runtime/components/page/PagePropertiesEditor.d.vue.ts +11 -0
- package/dist/runtime/components/page/PagePropertiesEditor.vue +111 -0
- package/dist/runtime/components/page/PagePropertiesEditor.vue.d.ts +11 -0
- package/dist/runtime/components/page/PagePropertiesRenderer.d.vue.ts +7 -0
- package/dist/runtime/components/page/PagePropertiesRenderer.vue +93 -0
- package/dist/runtime/components/page/PagePropertiesRenderer.vue.d.ts +7 -0
- package/dist/runtime/composables/useBlockEditor.d.ts +3262 -1
- package/dist/runtime/composables/useBlockEditor.js +6 -2
- package/dist/runtime/composables/usePageEditor.d.ts +10 -0
- package/dist/runtime/composables/usePageEditor.js +41 -0
- package/dist/runtime/types/blocks.d.ts +1 -0
- package/dist/runtime/types/pageTemplates.d.ts +3 -0
- package/dist/runtime/types/pageTemplates.js +170 -0
- package/dist/runtime/types/pages.d.ts +120 -0
- package/dist/runtime/types/pages.js +55 -0
- package/dist/runtime/utils/page.d.ts +7 -0
- package/dist/runtime/utils/page.js +33 -0
- package/package.json +1 -1
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -4,7 +4,7 @@ import { readdirSync } from 'node:fs';
|
|
|
4
4
|
import { basename } from 'node:path';
|
|
5
5
|
|
|
6
6
|
const name = "rimelight-components";
|
|
7
|
-
const version = "2.0.
|
|
7
|
+
const version = "2.0.50";
|
|
8
8
|
const homepage = "https://rimelight.com/tools/rimelight-components";
|
|
9
9
|
|
|
10
10
|
const defaultOptions = {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { Block } from "../../types/blocks.js";
|
|
2
2
|
export interface BlockEditorProps {
|
|
3
3
|
historyLimit?: number;
|
|
4
|
-
isSaving: boolean;
|
|
5
4
|
}
|
|
6
5
|
type __VLS_Props = BlockEditorProps;
|
|
7
6
|
export interface BlockEditorEmits {
|
|
@@ -11,7 +10,12 @@ type __VLS_ModelProps = {
|
|
|
11
10
|
modelValue: Block[];
|
|
12
11
|
};
|
|
13
12
|
type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
|
|
14
|
-
declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {
|
|
13
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {
|
|
14
|
+
undo: () => void;
|
|
15
|
+
redo: () => void;
|
|
16
|
+
canUndo: import("vue").ComputedRef<boolean>;
|
|
17
|
+
canRedo: import("vue").ComputedRef<boolean>;
|
|
18
|
+
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
15
19
|
"update:modelValue": (value: Block[]) => any;
|
|
16
20
|
} & {
|
|
17
21
|
save: () => any;
|
|
@@ -2,9 +2,8 @@
|
|
|
2
2
|
import { provide, ref, computed } from "vue";
|
|
3
3
|
import { useBlockEditor } from "../../composables/useBlockEditor";
|
|
4
4
|
const blocks = defineModel({ type: Array, ...{ required: true } });
|
|
5
|
-
const { historyLimit
|
|
6
|
-
historyLimit: { type: Number, required: false }
|
|
7
|
-
isSaving: { type: Boolean, required: true }
|
|
5
|
+
const { historyLimit } = defineProps({
|
|
6
|
+
historyLimit: { type: Number, required: false }
|
|
8
7
|
});
|
|
9
8
|
const emit = defineEmits(["save"]);
|
|
10
9
|
const {
|
|
@@ -29,6 +28,7 @@ provide("block-editor-api", {
|
|
|
29
28
|
undo,
|
|
30
29
|
redo
|
|
31
30
|
});
|
|
31
|
+
defineExpose({ undo, redo, canUndo, canRedo });
|
|
32
32
|
const handleSave = () => {
|
|
33
33
|
emit("save");
|
|
34
34
|
};
|
|
@@ -63,65 +63,5 @@ const redoAction = () => {
|
|
|
63
63
|
</script>
|
|
64
64
|
|
|
65
65
|
<template>
|
|
66
|
-
<
|
|
67
|
-
<template #left>
|
|
68
|
-
<div class="flex items-center gap-xs">
|
|
69
|
-
<UButton
|
|
70
|
-
icon="lucide:rotate-ccw"
|
|
71
|
-
variant="outline"
|
|
72
|
-
color="neutral"
|
|
73
|
-
size="xs"
|
|
74
|
-
:disabled="!canUndo"
|
|
75
|
-
@click="undoAction"
|
|
76
|
-
/>
|
|
77
|
-
<UButton
|
|
78
|
-
icon="lucide:rotate-cw"
|
|
79
|
-
variant="outline"
|
|
80
|
-
color="neutral"
|
|
81
|
-
size="xs"
|
|
82
|
-
:disabled="!canRedo"
|
|
83
|
-
@click="redoAction"
|
|
84
|
-
/>
|
|
85
|
-
</div>
|
|
86
|
-
</template>
|
|
87
|
-
|
|
88
|
-
<template #right>
|
|
89
|
-
<div class="flex items-center gap-xs">
|
|
90
|
-
<UButton
|
|
91
|
-
:icon="showPreview ? 'lucide:eye-off' : 'lucide:eye'"
|
|
92
|
-
label="Preview"
|
|
93
|
-
variant="outline"
|
|
94
|
-
color="neutral"
|
|
95
|
-
size="xs"
|
|
96
|
-
@click="togglePreview"
|
|
97
|
-
/>
|
|
98
|
-
<UButton
|
|
99
|
-
icon="lucide:save"
|
|
100
|
-
label="Save"
|
|
101
|
-
color="primary"
|
|
102
|
-
size="xs"
|
|
103
|
-
:loading="isSaving"
|
|
104
|
-
@click="handleSave"
|
|
105
|
-
/>
|
|
106
|
-
</div>
|
|
107
|
-
</template>
|
|
108
|
-
</UHeader>
|
|
109
|
-
<UPage>
|
|
110
|
-
<div :class="gridClass">
|
|
111
|
-
|
|
112
|
-
<div :class="editorPanelClass">
|
|
113
|
-
<RCBlockEditRenderer :blocks="blocks" />
|
|
114
|
-
</div>
|
|
115
|
-
|
|
116
|
-
<div
|
|
117
|
-
v-if="showPreview"
|
|
118
|
-
class="col-span-1 w-full"
|
|
119
|
-
>
|
|
120
|
-
<RCBlockViewRenderer
|
|
121
|
-
:blocks="blocks"
|
|
122
|
-
class="transition duration-300 opacity-100"
|
|
123
|
-
/>
|
|
124
|
-
</div>
|
|
125
|
-
</div>
|
|
126
|
-
</UPage>
|
|
66
|
+
<RCBlockEditRenderer :blocks="blocks" />
|
|
127
67
|
</template>
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { Block } from "../../types/blocks.js";
|
|
2
2
|
export interface BlockEditorProps {
|
|
3
3
|
historyLimit?: number;
|
|
4
|
-
isSaving: boolean;
|
|
5
4
|
}
|
|
6
5
|
type __VLS_Props = BlockEditorProps;
|
|
7
6
|
export interface BlockEditorEmits {
|
|
@@ -11,7 +10,12 @@ type __VLS_ModelProps = {
|
|
|
11
10
|
modelValue: Block[];
|
|
12
11
|
};
|
|
13
12
|
type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
|
|
14
|
-
declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {
|
|
13
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {
|
|
14
|
+
undo: () => void;
|
|
15
|
+
redo: () => void;
|
|
16
|
+
canUndo: import("vue").ComputedRef<boolean>;
|
|
17
|
+
canRedo: import("vue").ComputedRef<boolean>;
|
|
18
|
+
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
15
19
|
"update:modelValue": (value: Block[]) => any;
|
|
16
20
|
} & {
|
|
17
21
|
save: () => any;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Page } from "../../types/pages.js";
|
|
2
|
+
interface Props {
|
|
3
|
+
isSaving: boolean;
|
|
4
|
+
}
|
|
5
|
+
type __VLS_Props = Props;
|
|
6
|
+
type __VLS_ModelProps = {
|
|
7
|
+
modelValue: Page;
|
|
8
|
+
};
|
|
9
|
+
type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
|
|
10
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {
|
|
11
|
+
undo: () => void;
|
|
12
|
+
redo: () => void;
|
|
13
|
+
canUndo: import("vue").ComputedRef<boolean>;
|
|
14
|
+
canRedo: import("vue").ComputedRef<boolean>;
|
|
15
|
+
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
16
|
+
"update:modelValue": (value: Page) => any;
|
|
17
|
+
} & {
|
|
18
|
+
save: (value: Page) => any;
|
|
19
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
|
|
20
|
+
onSave?: ((value: Page) => any) | undefined;
|
|
21
|
+
"onUpdate:modelValue"?: ((value: Page) => any) | undefined;
|
|
22
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
23
|
+
declare const _default: typeof __VLS_export;
|
|
24
|
+
export default _default;
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { ref, computed, useTemplateRef } from "vue";
|
|
3
|
+
import { usePageEditor } from "../../composables/usePageEditor";
|
|
4
|
+
const page = defineModel({ type: Object, ...{ required: true } });
|
|
5
|
+
const { undo, redo, canUndo, canRedo, captureSnapshot } = usePageEditor(page);
|
|
6
|
+
const emit = defineEmits(["save"]);
|
|
7
|
+
const handleSave = () => {
|
|
8
|
+
const dataToPersist = JSON.parse(JSON.stringify(page.value));
|
|
9
|
+
emit("save", dataToPersist);
|
|
10
|
+
};
|
|
11
|
+
defineExpose({
|
|
12
|
+
undo,
|
|
13
|
+
redo,
|
|
14
|
+
canUndo,
|
|
15
|
+
canRedo
|
|
16
|
+
});
|
|
17
|
+
defineProps({
|
|
18
|
+
isSaving: { type: Boolean, required: true }
|
|
19
|
+
});
|
|
20
|
+
const editorRef = useTemplateRef("editor");
|
|
21
|
+
const showPreview = ref(false);
|
|
22
|
+
const editorPanelClass = computed(() => ({
|
|
23
|
+
// When the preview is visible, both editor/preview share 1/2 span.
|
|
24
|
+
"col-span-1 w-full": showPreview.value,
|
|
25
|
+
// When the preview is hidden, the editor uses the full grid space.
|
|
26
|
+
"col-span-2 w-full": !showPreview.value
|
|
27
|
+
}));
|
|
28
|
+
</script>
|
|
29
|
+
|
|
30
|
+
<template>
|
|
31
|
+
<UHeader class="fixed mt-16 top-0 left-0 z-50 h-12 w-full bg-muted">
|
|
32
|
+
<template #left>
|
|
33
|
+
<div class="flex items-center gap-xs">
|
|
34
|
+
<UButton
|
|
35
|
+
icon="lucide:rotate-ccw"
|
|
36
|
+
variant="outline"
|
|
37
|
+
color="neutral"
|
|
38
|
+
size="xs"
|
|
39
|
+
:disabled="!canUndo"
|
|
40
|
+
@click="undo"
|
|
41
|
+
/>
|
|
42
|
+
<UButton
|
|
43
|
+
icon="lucide:rotate-cw"
|
|
44
|
+
variant="outline"
|
|
45
|
+
color="neutral"
|
|
46
|
+
size="xs"
|
|
47
|
+
:disabled="!canRedo"
|
|
48
|
+
@click="redo"
|
|
49
|
+
/>
|
|
50
|
+
</div>
|
|
51
|
+
</template>
|
|
52
|
+
|
|
53
|
+
<template #right>
|
|
54
|
+
<div class="flex items-center gap-xs">
|
|
55
|
+
<UButton
|
|
56
|
+
:icon="showPreview ? 'lucide:eye-off' : 'lucide:eye'"
|
|
57
|
+
label="Preview"
|
|
58
|
+
variant="outline"
|
|
59
|
+
color="neutral"
|
|
60
|
+
size="xs"
|
|
61
|
+
@click="showPreview = !showPreview"
|
|
62
|
+
/>
|
|
63
|
+
<UButton
|
|
64
|
+
icon="lucide:save"
|
|
65
|
+
label="Save"
|
|
66
|
+
color="primary"
|
|
67
|
+
size="xs"
|
|
68
|
+
:loading="isSaving"
|
|
69
|
+
@click="handleSave"
|
|
70
|
+
/>
|
|
71
|
+
</div>
|
|
72
|
+
</template>
|
|
73
|
+
</UHeader>
|
|
74
|
+
|
|
75
|
+
<div class="mt-24 grid gap-xl" :class="showPreview ? 'grid-cols-2' : 'grid-cols-1'">
|
|
76
|
+
<UPage :class="editorPanelClass">
|
|
77
|
+
<template #default>
|
|
78
|
+
<RCBlockEditor
|
|
79
|
+
ref="editor"
|
|
80
|
+
v-model="page.blocks"
|
|
81
|
+
:class="editorPanelClass"
|
|
82
|
+
@mutation="captureSnapshot"
|
|
83
|
+
/>
|
|
84
|
+
</template>
|
|
85
|
+
<template #right>
|
|
86
|
+
<UPageAside>
|
|
87
|
+
<RCPagePropertiesEditor v-model="page" />
|
|
88
|
+
</UPageAside>
|
|
89
|
+
</template>
|
|
90
|
+
</UPage>
|
|
91
|
+
<UPage v-if="showPreview">
|
|
92
|
+
<template #default>
|
|
93
|
+
<RCBlockViewRenderer :blocks="page.blocks" />
|
|
94
|
+
</template>
|
|
95
|
+
<template #right>
|
|
96
|
+
<UPageAside>
|
|
97
|
+
<RCPagePropertiesRenderer v-model="page"/>
|
|
98
|
+
</UPageAside>
|
|
99
|
+
</template>
|
|
100
|
+
</UPage>
|
|
101
|
+
</div>
|
|
102
|
+
</template>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Page } from "../../types/pages.js";
|
|
2
|
+
interface Props {
|
|
3
|
+
isSaving: boolean;
|
|
4
|
+
}
|
|
5
|
+
type __VLS_Props = Props;
|
|
6
|
+
type __VLS_ModelProps = {
|
|
7
|
+
modelValue: Page;
|
|
8
|
+
};
|
|
9
|
+
type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
|
|
10
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {
|
|
11
|
+
undo: () => void;
|
|
12
|
+
redo: () => void;
|
|
13
|
+
canUndo: import("vue").ComputedRef<boolean>;
|
|
14
|
+
canRedo: import("vue").ComputedRef<boolean>;
|
|
15
|
+
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
16
|
+
"update:modelValue": (value: Page) => any;
|
|
17
|
+
} & {
|
|
18
|
+
save: (value: Page) => any;
|
|
19
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
|
|
20
|
+
onSave?: ((value: Page) => any) | undefined;
|
|
21
|
+
"onUpdate:modelValue"?: ((value: Page) => any) | undefined;
|
|
22
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
23
|
+
declare const _default: typeof __VLS_export;
|
|
24
|
+
export default _default;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type Page } from '../../types/pages.js';
|
|
2
|
+
type __VLS_ModelProps = {
|
|
3
|
+
modelValue: Page;
|
|
4
|
+
};
|
|
5
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
6
|
+
"update:modelValue": (value: Page) => any;
|
|
7
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_ModelProps> & Readonly<{
|
|
8
|
+
"onUpdate:modelValue"?: ((value: Page) => any) | undefined;
|
|
9
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
10
|
+
declare const _default: typeof __VLS_export;
|
|
11
|
+
export default _default;
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { computed } from "vue";
|
|
3
|
+
import { PAGE_SCHEMAS } from "../../types/pages";
|
|
4
|
+
const page = defineModel({ type: Object, ...{ required: true } });
|
|
5
|
+
const properties = computed(() => page.value.properties);
|
|
6
|
+
const groups = computed(() => {
|
|
7
|
+
return PAGE_SCHEMAS[page.value.type] || [];
|
|
8
|
+
});
|
|
9
|
+
const isFieldVisible = (fieldSchema) => {
|
|
10
|
+
if (!fieldSchema.visibleIf) return true;
|
|
11
|
+
return fieldSchema.visibleIf(page.value.properties);
|
|
12
|
+
};
|
|
13
|
+
const getSortedFields = (fields) => {
|
|
14
|
+
return Object.entries(fields).sort(([, a], [, b]) => (a.order ?? 0) - (b.order ?? 0));
|
|
15
|
+
};
|
|
16
|
+
</script>
|
|
17
|
+
|
|
18
|
+
<template>
|
|
19
|
+
<div class="flex flex-col gap-y-8 pr-2 pb-12">
|
|
20
|
+
<div class="flex items-center justify-between border-b border-border pb-4">
|
|
21
|
+
<h3 class="text-xs font-black uppercase tracking-widest text-muted-foreground">
|
|
22
|
+
{{ page.type }} Metadata
|
|
23
|
+
</h3>
|
|
24
|
+
<UBadge variant="subtle" size="sm" color="primary">
|
|
25
|
+
{{ page.slug }}
|
|
26
|
+
</UBadge>
|
|
27
|
+
</div>
|
|
28
|
+
|
|
29
|
+
<div v-for="group in groups" :key="group.id" class="space-y-4">
|
|
30
|
+
<div class="flex items-center gap-3">
|
|
31
|
+
<span class="text-[10px] font-bold uppercase tracking-widest text-primary">
|
|
32
|
+
{{ group.label }}
|
|
33
|
+
</span>
|
|
34
|
+
<div class="h-px flex-1 bg-border/50"></div>
|
|
35
|
+
</div>
|
|
36
|
+
|
|
37
|
+
<div class="grid gap-y-4 px-1">
|
|
38
|
+
<template v-for="[key, schema] in getSortedFields(group.fields)" :key="key">
|
|
39
|
+
|
|
40
|
+
<UFormField
|
|
41
|
+
v-if="isFieldVisible(schema)"
|
|
42
|
+
:label="schema.label"
|
|
43
|
+
:name="key"
|
|
44
|
+
>
|
|
45
|
+
<UInput
|
|
46
|
+
v-if="schema.type === 'text'"
|
|
47
|
+
v-model="properties[key]"
|
|
48
|
+
variant="subtle"
|
|
49
|
+
placeholder="..."
|
|
50
|
+
/>
|
|
51
|
+
|
|
52
|
+
<UInput
|
|
53
|
+
v-else-if="schema.type === 'number'"
|
|
54
|
+
v-model.number="properties[key]"
|
|
55
|
+
type="number"
|
|
56
|
+
variant="subtle"
|
|
57
|
+
/>
|
|
58
|
+
|
|
59
|
+
<USelect
|
|
60
|
+
v-else-if="schema.type === 'enum'"
|
|
61
|
+
v-model="properties[key]"
|
|
62
|
+
:items="schema.options || []"
|
|
63
|
+
variant="subtle"
|
|
64
|
+
/>
|
|
65
|
+
|
|
66
|
+
<UInputMenu
|
|
67
|
+
v-else-if="schema.type === 'text-array'"
|
|
68
|
+
v-model="properties[key]"
|
|
69
|
+
multiple
|
|
70
|
+
creatable
|
|
71
|
+
variant="subtle"
|
|
72
|
+
placeholder="Add item..."
|
|
73
|
+
/>
|
|
74
|
+
|
|
75
|
+
<UInput
|
|
76
|
+
v-else-if="schema.type === 'page'"
|
|
77
|
+
v-model="properties[key]"
|
|
78
|
+
icon="lucide:link-2"
|
|
79
|
+
variant="subtle"
|
|
80
|
+
:placeholder="`Select ${schema.allowedPageTypes?.join('/')}`"
|
|
81
|
+
/>
|
|
82
|
+
</UFormField>
|
|
83
|
+
</template>
|
|
84
|
+
</div>
|
|
85
|
+
</div>
|
|
86
|
+
|
|
87
|
+
<USeparator />
|
|
88
|
+
|
|
89
|
+
<UFormField label="Global Search Tags">
|
|
90
|
+
<UInputMenu
|
|
91
|
+
v-model="page.tags"
|
|
92
|
+
multiple
|
|
93
|
+
creatable
|
|
94
|
+
icon="lucide:tag"
|
|
95
|
+
variant="subtle"
|
|
96
|
+
placeholder="Add tags..."
|
|
97
|
+
/>
|
|
98
|
+
</UFormField>
|
|
99
|
+
|
|
100
|
+
<div class="mt-auto pt-6 text-[9px] font-mono text-muted-foreground/60 space-y-1">
|
|
101
|
+
<div class="flex justify-between">
|
|
102
|
+
<span>ID:</span>
|
|
103
|
+
<span>{{ page.id }}</span>
|
|
104
|
+
</div>
|
|
105
|
+
<div class="flex justify-between">
|
|
106
|
+
<span>Last Updated:</span>
|
|
107
|
+
<span>{{ new Date(page.updatedAt).toLocaleString() }}</span>
|
|
108
|
+
</div>
|
|
109
|
+
</div>
|
|
110
|
+
</div>
|
|
111
|
+
</template>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type Page } from '../../types/pages.js';
|
|
2
|
+
type __VLS_ModelProps = {
|
|
3
|
+
modelValue: Page;
|
|
4
|
+
};
|
|
5
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
6
|
+
"update:modelValue": (value: Page) => any;
|
|
7
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_ModelProps> & Readonly<{
|
|
8
|
+
"onUpdate:modelValue"?: ((value: Page) => any) | undefined;
|
|
9
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
10
|
+
declare const _default: typeof __VLS_export;
|
|
11
|
+
export default _default;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type Page } from '../../types/pages.js';
|
|
2
|
+
type __VLS_Props = {
|
|
3
|
+
modelValue: Page;
|
|
4
|
+
};
|
|
5
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
6
|
+
declare const _default: typeof __VLS_export;
|
|
7
|
+
export default _default;
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { computed } from "vue";
|
|
3
|
+
import {
|
|
4
|
+
PAGE_SCHEMAS
|
|
5
|
+
} from "../../types/pages";
|
|
6
|
+
const props = defineProps({
|
|
7
|
+
modelValue: { type: Object, required: true }
|
|
8
|
+
});
|
|
9
|
+
const properties = computed(() => props.modelValue.properties);
|
|
10
|
+
const displayGroups = computed(() => {
|
|
11
|
+
const allGroups = PAGE_SCHEMAS[props.modelValue.type] || [];
|
|
12
|
+
return allGroups.map((group) => {
|
|
13
|
+
const visibleFields = Object.entries(group.fields).filter(([key, schema]) => {
|
|
14
|
+
const value = properties.value[key];
|
|
15
|
+
const isVisible = !schema.visibleIf || schema.visibleIf(props.modelValue.properties);
|
|
16
|
+
if (!isVisible) return false;
|
|
17
|
+
if (Array.isArray(value)) return value.length > 0;
|
|
18
|
+
return value !== void 0 && value !== null && value !== "";
|
|
19
|
+
}).sort(([, a], [, b]) => (a.order ?? 0) - (b.order ?? 0));
|
|
20
|
+
return {
|
|
21
|
+
...group,
|
|
22
|
+
visibleFields
|
|
23
|
+
};
|
|
24
|
+
}).filter((group) => group.visibleFields.length > 0);
|
|
25
|
+
});
|
|
26
|
+
</script>
|
|
27
|
+
|
|
28
|
+
<template>
|
|
29
|
+
<div class="wiki-renderer flex flex-col border border-border rounded-lg bg-muted/20 overflow-hidden shadow-sm">
|
|
30
|
+
<div class="bg-muted/50 p-4 border-b border-border text-center">
|
|
31
|
+
<div class="text-[10px] font-bold uppercase tracking-widest text-muted-foreground/70 mb-1">
|
|
32
|
+
{{ props.modelValue.type }}
|
|
33
|
+
</div>
|
|
34
|
+
<h2 class="text-xl font-serif font-bold italic text-foreground">
|
|
35
|
+
{{ properties.name || props.modelValue.slug }}
|
|
36
|
+
</h2>
|
|
37
|
+
</div>
|
|
38
|
+
|
|
39
|
+
<div v-for="group in displayGroups" :key="group.id" class="border-b last:border-b-0 border-border/40">
|
|
40
|
+
<div class="bg-muted/30 px-3 py-1.5 text-[10px] font-black text-primary uppercase tracking-tighter border-b border-border/10">
|
|
41
|
+
{{ group.label }}
|
|
42
|
+
</div>
|
|
43
|
+
|
|
44
|
+
<dl class="p-3 space-y-2.5">
|
|
45
|
+
<div
|
|
46
|
+
v-for="[key, schema] in group.visibleFields"
|
|
47
|
+
:key="key"
|
|
48
|
+
class="grid grid-cols-3 gap-x-3 items-baseline"
|
|
49
|
+
>
|
|
50
|
+
<dt class="text-[11px] font-semibold text-muted-foreground leading-tight">
|
|
51
|
+
{{ schema.label }}
|
|
52
|
+
</dt>
|
|
53
|
+
|
|
54
|
+
<dd class="text-xs col-span-2 text-foreground leading-snug">
|
|
55
|
+
<div v-if="schema.type === 'text-array'" class="flex flex-wrap gap-1">
|
|
56
|
+
<template v-for="(item, index) in properties[key]" :key="index">
|
|
57
|
+
<span class="font-medium">{{ item }}</span>
|
|
58
|
+
<span v-if="index < properties[key].length - 1" class="text-muted-foreground/50">, </span>
|
|
59
|
+
</template>
|
|
60
|
+
</div>
|
|
61
|
+
|
|
62
|
+
<span v-else-if="schema.type === 'page'" class="text-primary font-bold hover:underline cursor-pointer">
|
|
63
|
+
{{ properties[key] }}
|
|
64
|
+
</span>
|
|
65
|
+
|
|
66
|
+
<span v-else class="font-medium">
|
|
67
|
+
{{ properties[key] }}
|
|
68
|
+
</span>
|
|
69
|
+
</dd>
|
|
70
|
+
</div>
|
|
71
|
+
</dl>
|
|
72
|
+
</div>
|
|
73
|
+
|
|
74
|
+
<div v-if="props.modelValue.tags?.length" class="p-3 bg-background/50 border-t border-border">
|
|
75
|
+
<div class="flex flex-wrap gap-1.5">
|
|
76
|
+
<UBadge
|
|
77
|
+
v-for="tag in props.modelValue.tags"
|
|
78
|
+
:key="tag"
|
|
79
|
+
variant="subtle"
|
|
80
|
+
size="sm"
|
|
81
|
+
color="neutral"
|
|
82
|
+
class="text-[9px] font-bold uppercase tracking-tight"
|
|
83
|
+
>
|
|
84
|
+
#{{ tag }}
|
|
85
|
+
</UBadge>
|
|
86
|
+
</div>
|
|
87
|
+
</div>
|
|
88
|
+
</div>
|
|
89
|
+
</template>
|
|
90
|
+
|
|
91
|
+
<style scoped>
|
|
92
|
+
.font-serif{font-family:Georgia,Times New Roman,Times,serif}
|
|
93
|
+
</style>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type Page } from '../../types/pages.js';
|
|
2
|
+
type __VLS_Props = {
|
|
3
|
+
modelValue: Page;
|
|
4
|
+
};
|
|
5
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
6
|
+
declare const _default: typeof __VLS_export;
|
|
7
|
+
export default _default;
|