rimelight-components 2.0.44 → 2.0.46
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/Block.d.vue.ts +30 -0
- package/dist/runtime/components/blocks/Block.vue +89 -0
- package/dist/runtime/components/blocks/Block.vue.d.ts +30 -0
- package/dist/runtime/components/blocks/editor/CalloutBlockEditor.vue +0 -2
- package/dist/runtime/components/blocks/editor/CardBlockEditor.d.vue.ts +4 -0
- package/dist/runtime/components/blocks/editor/CardBlockEditor.vue +18 -0
- package/dist/runtime/components/blocks/editor/CardBlockEditor.vue.d.ts +4 -0
- package/dist/runtime/components/blocks/editor/ImageBlockEditor.d.vue.ts +14 -0
- package/dist/runtime/components/blocks/editor/ImageBlockEditor.vue +119 -0
- package/dist/runtime/components/blocks/editor/ImageBlockEditor.vue.d.ts +14 -0
- package/dist/runtime/components/blocks/editor/ParagraphBlockEditor.d.vue.ts +4 -0
- package/dist/runtime/components/blocks/editor/ParagraphBlockEditor.vue +11 -0
- package/dist/runtime/components/blocks/editor/ParagraphBlockEditor.vue.d.ts +4 -0
- package/dist/runtime/components/blocks/editor/SectionBlockEditor.vue +11 -7
- package/dist/runtime/components/content/Section.vue +2 -3
- package/dist/runtime/components/renderers/BlockEditor.vue +17 -18
- 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.46";
|
|
8
8
|
const homepage = "https://rimelight.com/tools/rimelight-components";
|
|
9
9
|
|
|
10
10
|
const defaultOptions = {
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
type __VLS_Props = {
|
|
2
|
+
id: string;
|
|
3
|
+
};
|
|
4
|
+
declare var __VLS_13: {};
|
|
5
|
+
type __VLS_Slots = {} & {
|
|
6
|
+
default?: (props: typeof __VLS_13) => any;
|
|
7
|
+
};
|
|
8
|
+
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
9
|
+
moveBlockUp: (id: string) => any;
|
|
10
|
+
moveBlockDown: (id: string) => any;
|
|
11
|
+
addBlockAbove: (id: string) => any;
|
|
12
|
+
addBlockBelow: (id: string) => any;
|
|
13
|
+
duplicateBlock: (id: string) => any;
|
|
14
|
+
deleteBlock: (id: string) => any;
|
|
15
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
16
|
+
onMoveBlockUp?: ((id: string) => any) | undefined;
|
|
17
|
+
onMoveBlockDown?: ((id: string) => any) | undefined;
|
|
18
|
+
onAddBlockAbove?: ((id: string) => any) | undefined;
|
|
19
|
+
onAddBlockBelow?: ((id: string) => any) | undefined;
|
|
20
|
+
onDuplicateBlock?: ((id: string) => any) | undefined;
|
|
21
|
+
onDeleteBlock?: ((id: string) => any) | undefined;
|
|
22
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
23
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
24
|
+
declare const _default: typeof __VLS_export;
|
|
25
|
+
export default _default;
|
|
26
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
27
|
+
new (): {
|
|
28
|
+
$slots: S;
|
|
29
|
+
};
|
|
30
|
+
};
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { ref } from "vue";
|
|
3
|
+
const {
|
|
4
|
+
id
|
|
5
|
+
} = defineProps({
|
|
6
|
+
id: { type: String, required: true }
|
|
7
|
+
});
|
|
8
|
+
const emit = defineEmits(["moveBlockUp", "moveBlockDown", "addBlockAbove", "addBlockBelow", "duplicateBlock", "deleteBlock"]);
|
|
9
|
+
const handleMoveBlockUp = () => {
|
|
10
|
+
emit("moveBlockUp", id);
|
|
11
|
+
console.log(`Emitting 'moveBlockUp' for ID: ${id}`);
|
|
12
|
+
};
|
|
13
|
+
const handleMoveBlockDown = () => {
|
|
14
|
+
emit("moveBlockDown", id);
|
|
15
|
+
console.log(`Emitting 'moveBlockDown' for ID: ${id}`);
|
|
16
|
+
};
|
|
17
|
+
const handleAddBlockAbove = () => {
|
|
18
|
+
emit("addBlockAbove", id);
|
|
19
|
+
console.log(`Emitting 'addBlockAbove' for ID: ${id}`);
|
|
20
|
+
};
|
|
21
|
+
const handleAddBlockBelow = () => {
|
|
22
|
+
emit("addBlockBelow", id);
|
|
23
|
+
console.log(`Emitting 'addBlockBelow' for ID: ${id}`);
|
|
24
|
+
};
|
|
25
|
+
const handleDuplicateBlock = () => {
|
|
26
|
+
emit("duplicateBlock", id);
|
|
27
|
+
console.log(`Emitting 'duplicateBlock' for ID: ${id}`);
|
|
28
|
+
};
|
|
29
|
+
const handleDeleteBlock = () => {
|
|
30
|
+
emit("deleteBlock", id);
|
|
31
|
+
console.log(`Emitting 'deleteBlock' for ID: ${id}`);
|
|
32
|
+
};
|
|
33
|
+
const items = ref([
|
|
34
|
+
[
|
|
35
|
+
{
|
|
36
|
+
icon: "lucide:arrow-up",
|
|
37
|
+
label: "Move Block Up",
|
|
38
|
+
click: handleMoveBlockUp
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
icon: "lucide:arrow-down",
|
|
42
|
+
label: "Move Block Down",
|
|
43
|
+
click: handleMoveBlockDown
|
|
44
|
+
}
|
|
45
|
+
],
|
|
46
|
+
[
|
|
47
|
+
{
|
|
48
|
+
icon: "lucide:corner-right-up",
|
|
49
|
+
label: "Add Block Above",
|
|
50
|
+
click: handleAddBlockAbove
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
icon: "lucide:corner-right-down",
|
|
54
|
+
label: "Add Block Below",
|
|
55
|
+
click: handleAddBlockBelow
|
|
56
|
+
}
|
|
57
|
+
],
|
|
58
|
+
[
|
|
59
|
+
{
|
|
60
|
+
icon: "lucide:copy-plus",
|
|
61
|
+
label: "Duplicate Block",
|
|
62
|
+
click: handleDuplicateBlock
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
color: "error",
|
|
66
|
+
icon: "lucide:trash-2",
|
|
67
|
+
label: "Delete Block",
|
|
68
|
+
click: handleDeleteBlock
|
|
69
|
+
}
|
|
70
|
+
]
|
|
71
|
+
]);
|
|
72
|
+
</script>
|
|
73
|
+
|
|
74
|
+
<template>
|
|
75
|
+
<div class="relative group">
|
|
76
|
+
<div
|
|
77
|
+
class=" absolute top-0 -ms-10 left-0
|
|
78
|
+
z-10 opacity-0 group-hover:opacity-100 transition-opacity"
|
|
79
|
+
>
|
|
80
|
+
<UDropdownMenu
|
|
81
|
+
:items="items"
|
|
82
|
+
>
|
|
83
|
+
<UButton icon="lucide:grip-vertical" variant="ghost" color="neutral"/>
|
|
84
|
+
</UDropdownMenu>
|
|
85
|
+
</div>
|
|
86
|
+
|
|
87
|
+
<slot/>
|
|
88
|
+
</div>
|
|
89
|
+
</template>
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
type __VLS_Props = {
|
|
2
|
+
id: string;
|
|
3
|
+
};
|
|
4
|
+
declare var __VLS_13: {};
|
|
5
|
+
type __VLS_Slots = {} & {
|
|
6
|
+
default?: (props: typeof __VLS_13) => any;
|
|
7
|
+
};
|
|
8
|
+
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
9
|
+
moveBlockUp: (id: string) => any;
|
|
10
|
+
moveBlockDown: (id: string) => any;
|
|
11
|
+
addBlockAbove: (id: string) => any;
|
|
12
|
+
addBlockBelow: (id: string) => any;
|
|
13
|
+
duplicateBlock: (id: string) => any;
|
|
14
|
+
deleteBlock: (id: string) => any;
|
|
15
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
16
|
+
onMoveBlockUp?: ((id: string) => any) | undefined;
|
|
17
|
+
onMoveBlockDown?: ((id: string) => any) | undefined;
|
|
18
|
+
onAddBlockAbove?: ((id: string) => any) | undefined;
|
|
19
|
+
onAddBlockBelow?: ((id: string) => any) | undefined;
|
|
20
|
+
onDuplicateBlock?: ((id: string) => any) | undefined;
|
|
21
|
+
onDeleteBlock?: ((id: string) => any) | undefined;
|
|
22
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
23
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
24
|
+
declare const _default: typeof __VLS_export;
|
|
25
|
+
export default _default;
|
|
26
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
27
|
+
new (): {
|
|
28
|
+
$slots: S;
|
|
29
|
+
};
|
|
30
|
+
};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { CardBlockProps } from "~~/src/runtime/types/blocks";
|
|
2
|
+
declare const __VLS_export: import("vue").DefineComponent<CardBlockProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<CardBlockProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
3
|
+
declare const _default: typeof __VLS_export;
|
|
4
|
+
export default _default;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
const { title, to, target, children } = defineProps({
|
|
3
|
+
title: { type: String, required: true },
|
|
4
|
+
to: { type: String, required: false },
|
|
5
|
+
target: { type: String, required: false },
|
|
6
|
+
description: { type: String, required: false },
|
|
7
|
+
children: { type: Array, required: true }
|
|
8
|
+
});
|
|
9
|
+
</script>
|
|
10
|
+
|
|
11
|
+
<template>
|
|
12
|
+
<NuxtLink :to="to" :target="target">
|
|
13
|
+
<UCard class="flex h-full flex-col">
|
|
14
|
+
<h3>{{ title }}</h3>
|
|
15
|
+
<RCBlockRenderer :blocks="children" />
|
|
16
|
+
</UCard>
|
|
17
|
+
</NuxtLink>
|
|
18
|
+
</template>
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { CardBlockProps } from "~~/src/runtime/types/blocks";
|
|
2
|
+
declare const __VLS_export: import("vue").DefineComponent<CardBlockProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<CardBlockProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
3
|
+
declare const _default: typeof __VLS_export;
|
|
4
|
+
export default _default;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ImageBlockProps } from "~~/src/runtime/types/blocks";
|
|
2
|
+
declare const __VLS_export: import("vue").DefineComponent<ImageBlockProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
3
|
+
"update:src": (value: string | null) => any;
|
|
4
|
+
"update:alt": (value: string) => any;
|
|
5
|
+
"update:caption": (value: string | null) => any;
|
|
6
|
+
"update:file": (value: File | null) => any;
|
|
7
|
+
}, string, import("vue").PublicProps, Readonly<ImageBlockProps> & Readonly<{
|
|
8
|
+
"onUpdate:src"?: ((value: string | null) => any) | undefined;
|
|
9
|
+
"onUpdate:alt"?: ((value: string) => any) | undefined;
|
|
10
|
+
"onUpdate:caption"?: ((value: string | null) => any) | undefined;
|
|
11
|
+
"onUpdate:file"?: ((value: File | null) => any) | undefined;
|
|
12
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
13
|
+
declare const _default: typeof __VLS_export;
|
|
14
|
+
export default _default;
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { ref, watch, computed } from "vue";
|
|
3
|
+
import { useObjectUrl } from "@vueuse/core";
|
|
4
|
+
const props = defineProps({
|
|
5
|
+
src: { type: String, required: true },
|
|
6
|
+
alt: { type: String, required: true },
|
|
7
|
+
caption: { type: String, required: false }
|
|
8
|
+
});
|
|
9
|
+
const emit = defineEmits(["update:src", "update:alt", "update:caption", "update:file"]);
|
|
10
|
+
const fileToUpload = ref(null);
|
|
11
|
+
const localAlt = ref(props.alt || "");
|
|
12
|
+
const localCaption = ref(props.caption || "");
|
|
13
|
+
const filePreviewUrl = useObjectUrl(fileToUpload);
|
|
14
|
+
const previewSrc = computed(() => {
|
|
15
|
+
return fileToUpload.value ? filePreviewUrl.value : props.src;
|
|
16
|
+
});
|
|
17
|
+
const removeFile = () => {
|
|
18
|
+
fileToUpload.value = null;
|
|
19
|
+
emit("update:file", null);
|
|
20
|
+
emit("update:src", null);
|
|
21
|
+
};
|
|
22
|
+
watch(localAlt, (newVal) => {
|
|
23
|
+
emit("update:alt", newVal);
|
|
24
|
+
});
|
|
25
|
+
watch(localCaption, (newVal) => {
|
|
26
|
+
emit("update:caption", newVal.trim() || null);
|
|
27
|
+
});
|
|
28
|
+
watch(fileToUpload, (newFile) => {
|
|
29
|
+
emit("update:file", newFile);
|
|
30
|
+
});
|
|
31
|
+
</script>
|
|
32
|
+
|
|
33
|
+
<template>
|
|
34
|
+
<figure class="mx-auto space-y-4 flex flex-col gap-xs w-full">
|
|
35
|
+
<UFileUpload
|
|
36
|
+
v-slot="{ open }"
|
|
37
|
+
v-model="fileToUpload"
|
|
38
|
+
accept="image/*"
|
|
39
|
+
class="min-h-48 w-full"
|
|
40
|
+
variant="area"
|
|
41
|
+
color="neutral"
|
|
42
|
+
label="Drop image here"
|
|
43
|
+
description="JPG, PNG, GIF or WEBP. Click to select."
|
|
44
|
+
>
|
|
45
|
+
<div class="flex flex-col items-center justify-center space-y-3 p-4">
|
|
46
|
+
<div class="w-full relative rounded-lg border border-default overflow-hidden">
|
|
47
|
+
<img
|
|
48
|
+
v-if="previewSrc"
|
|
49
|
+
:src="previewSrc"
|
|
50
|
+
:alt="localAlt || 'Image preview'"
|
|
51
|
+
class="w-full h-auto object-contain transition-opacity duration-300"
|
|
52
|
+
/>
|
|
53
|
+
<div v-else class="w-full h-48 flex items-center justify-center bg-elevated/25">
|
|
54
|
+
<UIcon name="i-lucide-image" class="w-10 h-10 text-muted" />
|
|
55
|
+
</div>
|
|
56
|
+
|
|
57
|
+
<div
|
|
58
|
+
class="absolute inset-0 flex items-center justify-center bg-black bg-opacity-40 opacity-0 hover:opacity-100 transition-opacity"
|
|
59
|
+
>
|
|
60
|
+
<div class="flex space-x-2">
|
|
61
|
+
<UButton
|
|
62
|
+
icon="i-lucide-upload"
|
|
63
|
+
:label="previewSrc ? 'Change Image' : 'Select Image'"
|
|
64
|
+
color="neutral"
|
|
65
|
+
@click="open()"
|
|
66
|
+
/>
|
|
67
|
+
<UButton
|
|
68
|
+
v-if="previewSrc"
|
|
69
|
+
icon="i-lucide-trash-2"
|
|
70
|
+
label="Remove"
|
|
71
|
+
color="error"
|
|
72
|
+
variant="outline"
|
|
73
|
+
@click="removeFile()"
|
|
74
|
+
/>
|
|
75
|
+
</div>
|
|
76
|
+
</div>
|
|
77
|
+
</div>
|
|
78
|
+
</div>
|
|
79
|
+
</UFileUpload>
|
|
80
|
+
|
|
81
|
+
<UInput
|
|
82
|
+
v-model="localAlt"
|
|
83
|
+
type="text"
|
|
84
|
+
placeholder="Alt text (accessibility)"
|
|
85
|
+
class="w-full"
|
|
86
|
+
variant="outline"
|
|
87
|
+
>
|
|
88
|
+
<template #leading>
|
|
89
|
+
<UTooltip>
|
|
90
|
+
<template #default>
|
|
91
|
+
<span class="text-xs text-muted">Alt</span>
|
|
92
|
+
</template>
|
|
93
|
+
<template #content>
|
|
94
|
+
The text description for the image used by screen readers.
|
|
95
|
+
</template>
|
|
96
|
+
</UTooltip>
|
|
97
|
+
</template>
|
|
98
|
+
</UInput>
|
|
99
|
+
|
|
100
|
+
<UTextarea
|
|
101
|
+
v-model="localCaption"
|
|
102
|
+
autoresize
|
|
103
|
+
placeholder="Caption (optional)"
|
|
104
|
+
class="w-full"
|
|
105
|
+
variant="outline"
|
|
106
|
+
>
|
|
107
|
+
<template #leading>
|
|
108
|
+
<UTooltip>
|
|
109
|
+
<template #default>
|
|
110
|
+
<span class="text-xs text-muted">Caption</span>
|
|
111
|
+
</template>
|
|
112
|
+
<template #content>
|
|
113
|
+
The text description for the image used by screen readers.
|
|
114
|
+
</template>
|
|
115
|
+
</UTooltip>
|
|
116
|
+
</template>
|
|
117
|
+
</UTextarea>
|
|
118
|
+
</figure>
|
|
119
|
+
</template>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ImageBlockProps } from "~~/src/runtime/types/blocks";
|
|
2
|
+
declare const __VLS_export: import("vue").DefineComponent<ImageBlockProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
3
|
+
"update:src": (value: string | null) => any;
|
|
4
|
+
"update:alt": (value: string) => any;
|
|
5
|
+
"update:caption": (value: string | null) => any;
|
|
6
|
+
"update:file": (value: File | null) => any;
|
|
7
|
+
}, string, import("vue").PublicProps, Readonly<ImageBlockProps> & Readonly<{
|
|
8
|
+
"onUpdate:src"?: ((value: string | null) => any) | undefined;
|
|
9
|
+
"onUpdate:alt"?: ((value: string) => any) | undefined;
|
|
10
|
+
"onUpdate:caption"?: ((value: string | null) => any) | undefined;
|
|
11
|
+
"onUpdate:file"?: ((value: File | null) => any) | undefined;
|
|
12
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
13
|
+
declare const _default: typeof __VLS_export;
|
|
14
|
+
export default _default;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { ParagraphBlockProps } from "~~/src/runtime/types/blocks";
|
|
2
|
+
declare const __VLS_export: import("vue").DefineComponent<ParagraphBlockProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<ParagraphBlockProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
3
|
+
declare const _default: typeof __VLS_export;
|
|
4
|
+
export default _default;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { ParagraphBlockProps } from "~~/src/runtime/types/blocks";
|
|
2
|
+
declare const __VLS_export: import("vue").DefineComponent<ParagraphBlockProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<ParagraphBlockProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
3
|
+
declare const _default: typeof __VLS_export;
|
|
4
|
+
export default _default;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
-
import { computed } from "vue";
|
|
2
|
+
import { computed, ref, watch } from "vue";
|
|
3
3
|
import { slugify } from "../../../utils";
|
|
4
4
|
const { level, title, description, children } = defineProps({
|
|
5
5
|
level: { type: Number, required: true },
|
|
@@ -7,6 +7,10 @@ const { level, title, description, children } = defineProps({
|
|
|
7
7
|
description: { type: String, required: false },
|
|
8
8
|
children: { type: Array, required: true }
|
|
9
9
|
});
|
|
10
|
+
const titleCharacterCount = 128;
|
|
11
|
+
const descriptionCharacterCount = 256;
|
|
12
|
+
const localTitle = ref(title || "");
|
|
13
|
+
const localDescription = ref(description || "");
|
|
10
14
|
const headingId = computed(() => title ? slugify(title) : void 0);
|
|
11
15
|
</script>
|
|
12
16
|
|
|
@@ -18,30 +22,30 @@ const headingId = computed(() => title ? slugify(title) : void 0);
|
|
|
18
22
|
:id="headingId"
|
|
19
23
|
>
|
|
20
24
|
<template #title>
|
|
21
|
-
<UInput
|
|
25
|
+
<UInput v-model="localTitle" :maxlength="titleCharacterCount" type="text" variant="ghost" placeholder="Section title" class="w-full">
|
|
22
26
|
<template #trailing>
|
|
23
27
|
<div
|
|
24
28
|
id="character-count"
|
|
25
|
-
class="text-xs text-
|
|
29
|
+
class="text-xs text-dimmed tabular-nums"
|
|
26
30
|
aria-live="polite"
|
|
27
31
|
role="status"
|
|
28
32
|
>
|
|
29
|
-
{{
|
|
33
|
+
{{ localTitle?.length }}/{{ titleCharacterCount }}
|
|
30
34
|
</div>
|
|
31
35
|
</template>
|
|
32
36
|
</UInput>
|
|
33
37
|
</template>
|
|
34
38
|
|
|
35
39
|
<template #description>
|
|
36
|
-
<UTextarea
|
|
40
|
+
<UTextarea v-model="localDescription" :maxlength="descriptionCharacterCount" variant="ghost" autoresize placeholder="Section description" class="w-full">
|
|
37
41
|
<template #trailing>
|
|
38
42
|
<div
|
|
39
43
|
id="character-count"
|
|
40
|
-
class="text-xs text-
|
|
44
|
+
class="text-xs text-dimmed tabular-nums"
|
|
41
45
|
aria-live="polite"
|
|
42
46
|
role="status"
|
|
43
47
|
>
|
|
44
|
-
{{
|
|
48
|
+
{{ localDescription?.length }}/{{ descriptionCharacterCount }}
|
|
45
49
|
</div>
|
|
46
50
|
</template>
|
|
47
51
|
</UTextarea>
|
|
@@ -26,9 +26,9 @@ const copyToClipboard = async (text) => {
|
|
|
26
26
|
};
|
|
27
27
|
const sectionVariants = tv({
|
|
28
28
|
slots: {
|
|
29
|
-
sectionSlot: "flex flex-col
|
|
29
|
+
sectionSlot: "flex flex-col scroll-mt-24 w-full",
|
|
30
30
|
linkSlot: "",
|
|
31
|
-
headingSlot: "font-bold",
|
|
31
|
+
headingSlot: "font-bold w-full",
|
|
32
32
|
descriptionSlot: "text-muted",
|
|
33
33
|
separatorSlot: "py-2",
|
|
34
34
|
contentSlot: "flex flex-col gap-md mt-2"
|
|
@@ -119,7 +119,6 @@ const fullSectionUrl = computed(() => {
|
|
|
119
119
|
:id="sectionId"
|
|
120
120
|
:is="`h${level}`"
|
|
121
121
|
:class="headingSlot()"
|
|
122
|
-
class="relative"
|
|
123
122
|
>
|
|
124
123
|
<NuxtLink
|
|
125
124
|
v-if="!isEditing"
|
|
@@ -36,29 +36,28 @@ const getComponent = (block) => {
|
|
|
36
36
|
title="Start adding content blocks."
|
|
37
37
|
description="There is no content yet. Use the '+' button below to add your first block."
|
|
38
38
|
/>
|
|
39
|
-
<
|
|
40
|
-
<template v-
|
|
41
|
-
<
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
39
|
+
<div v-else class="flex flex-col gap-md ml-10">
|
|
40
|
+
<template v-for="block in blocks" :key="block.id">
|
|
41
|
+
<RCBlock v-if="getComponent(block)" :id="block.id">
|
|
42
|
+
<component
|
|
43
|
+
:is="getComponent(block)"
|
|
44
|
+
v-bind="block.props"
|
|
45
|
+
:is-editing="true"
|
|
46
|
+
:key="block.id"
|
|
47
|
+
:type="block.type"
|
|
48
|
+
class="block-editor-container"
|
|
49
|
+
/>
|
|
50
|
+
</RCBlock>
|
|
51
|
+
<template v-else>
|
|
52
|
+
<UAlert
|
|
51
53
|
color="warning"
|
|
52
54
|
variant="subtle"
|
|
53
55
|
icon="lucide:octagon-alert"
|
|
54
56
|
title="Editor Rendering Error"
|
|
55
57
|
:description="`Editor component for type \'${block.type || 'UNKNOWN_OR_MISSING'}\' was not found. Please ensure the block name is correct and the editor component exists in the \'editor\' subdirectory.`"
|
|
56
|
-
|
|
58
|
+
/>
|
|
59
|
+
</template>
|
|
57
60
|
</template>
|
|
58
|
-
</
|
|
61
|
+
</div>
|
|
59
62
|
</div>
|
|
60
63
|
</template>
|
|
61
|
-
|
|
62
|
-
<style scoped>
|
|
63
|
-
.editor-block-renderer{min-height:200px;padding:1rem}
|
|
64
|
-
</style>
|