@vigilkids/section-renderer-vue 0.2.2 → 0.5.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.
- package/dist/interactions/vigilkids.d.ts +44 -1
- package/dist/interactions/vigilkids.mjs +115 -1
- package/dist/sections/article/index.mjs +60 -0
- package/dist/sections/article/vigilkids/ArticleFaq.vue +9 -2
- package/dist/sections/article/vigilkids/ArticleFaqItem.d.vue.ts +3 -0
- package/dist/sections/article/vigilkids/ArticleFaqItem.vue +18 -18
- package/dist/sections/article/vigilkids/ArticleFaqItem.vue.d.ts +3 -0
- package/dist/sections/article/vigilkids/ArticleHeading.vue +2 -1
- package/dist/sections/article/vigilkids/ArticleHighlightParagraph.d.vue.ts +21 -0
- package/dist/sections/article/vigilkids/ArticleHighlightParagraph.vue +38 -0
- package/dist/sections/article/vigilkids/ArticleHighlightParagraph.vue.d.ts +21 -0
- package/dist/sections/article/vigilkids/ArticleProductCard.d.vue.ts +21 -0
- package/dist/sections/article/vigilkids/ArticleProductCard.vue +65 -0
- package/dist/sections/article/vigilkids/ArticleProductCard.vue.d.ts +21 -0
- package/dist/sections/article/vigilkids/ArticleProductInfoBanner.d.vue.ts +21 -0
- package/dist/sections/article/vigilkids/ArticleProductInfoBanner.vue +56 -0
- package/dist/sections/article/vigilkids/ArticleProductInfoBanner.vue.d.ts +21 -0
- package/dist/sections/article/vigilkids/ArticleRelatedArticles.d.vue.ts +21 -0
- package/dist/sections/article/vigilkids/ArticleRelatedArticles.vue +86 -0
- package/dist/sections/article/vigilkids/ArticleRelatedArticles.vue.d.ts +21 -0
- package/dist/sections/article/vigilkids/ArticleRetentionBanner.d.vue.ts +21 -0
- package/dist/sections/article/vigilkids/ArticleRetentionBanner.vue +100 -0
- package/dist/sections/article/vigilkids/ArticleRetentionBanner.vue.d.ts +21 -0
- package/dist/sections/article/vigilkids/ArticleSectionIntro.d.vue.ts +21 -0
- package/dist/sections/article/vigilkids/ArticleSectionIntro.vue +56 -0
- package/dist/sections/article/vigilkids/ArticleSectionIntro.vue.d.ts +21 -0
- package/dist/sections/article/vigilkids/ArticleStepList.vue +11 -6
- package/dist/sections/article/vigilkids/ArticleStyledHeading.d.vue.ts +21 -0
- package/dist/sections/article/vigilkids/ArticleStyledHeading.vue +48 -0
- package/dist/sections/article/vigilkids/ArticleStyledHeading.vue.d.ts +21 -0
- package/dist/sections/article/vigilkids/ArticleSubheading.vue +5 -4
- package/dist/sections/article/vigilkids/ArticleTable.d.vue.ts +13 -1
- package/dist/sections/article/vigilkids/ArticleTable.vue +26 -6
- package/dist/sections/article/vigilkids/ArticleTable.vue.d.ts +13 -1
- package/dist/sections/article/vigilkids/ArticleTipNote.d.vue.ts +21 -0
- package/dist/sections/article/vigilkids/ArticleTipNote.vue +58 -0
- package/dist/sections/article/vigilkids/ArticleTipNote.vue.d.ts +21 -0
- package/dist/sections/article/vigilkids/ArticleToc.vue +22 -7
- package/dist/sections/article/vigilkids/ArticleTocList.d.vue.ts +21 -0
- package/dist/sections/article/vigilkids/ArticleTocList.vue +56 -0
- package/dist/sections/article/vigilkids/ArticleTocList.vue.d.ts +21 -0
- package/dist/sections/article/vigilkids/ArticleTopAd.d.vue.ts +21 -0
- package/dist/sections/article/vigilkids/ArticleTopAd.vue +90 -0
- package/dist/sections/article/vigilkids/ArticleTopAd.vue.d.ts +21 -0
- package/dist/sections/article/vigilkids/product-card/ProductCardCtaGroup.d.vue.ts +6 -0
- package/dist/sections/article/vigilkids/product-card/ProductCardCtaGroup.vue +21 -0
- package/dist/sections/article/vigilkids/product-card/ProductCardCtaGroup.vue.d.ts +6 -0
- package/dist/sections/article/vigilkids/product-card/ProductCardVariantA.d.vue.ts +21 -0
- package/dist/sections/article/vigilkids/product-card/ProductCardVariantA.vue +46 -0
- package/dist/sections/article/vigilkids/product-card/ProductCardVariantA.vue.d.ts +21 -0
- package/dist/sections/article/vigilkids/product-card/ProductCardVariantB.d.vue.ts +21 -0
- package/dist/sections/article/vigilkids/product-card/ProductCardVariantB.vue +46 -0
- package/dist/sections/article/vigilkids/product-card/ProductCardVariantB.vue.d.ts +21 -0
- package/dist/sections/article/vigilkids/product-card/ProductCardVariantC.d.vue.ts +21 -0
- package/dist/sections/article/vigilkids/product-card/ProductCardVariantC.vue +46 -0
- package/dist/sections/article/vigilkids/product-card/ProductCardVariantC.vue.d.ts +21 -0
- package/dist/sections/article/vigilkids/product-card/ProductCardVariantD.d.vue.ts +21 -0
- package/dist/sections/article/vigilkids/product-card/ProductCardVariantD.vue +56 -0
- package/dist/sections/article/vigilkids/product-card/ProductCardVariantD.vue.d.ts +21 -0
- package/dist/sections/article/vigilkids/product-card/ProductCardVariantE.d.vue.ts +21 -0
- package/dist/sections/article/vigilkids/product-card/ProductCardVariantE.vue +55 -0
- package/dist/sections/article/vigilkids/product-card/ProductCardVariantE.vue.d.ts +21 -0
- package/dist/sections/article/vigilkids/product-card/ProductCardVariantF.d.vue.ts +21 -0
- package/dist/sections/article/vigilkids/product-card/ProductCardVariantF.vue +56 -0
- package/dist/sections/article/vigilkids/product-card/ProductCardVariantF.vue.d.ts +21 -0
- package/dist/sections/article/vigilkids/product-card/ProductCardVariantG.d.vue.ts +21 -0
- package/dist/sections/article/vigilkids/product-card/ProductCardVariantG.vue +52 -0
- package/dist/sections/article/vigilkids/product-card/ProductCardVariantG.vue.d.ts +21 -0
- package/dist/styles/products/vigilkids.css +1 -1
- package/dist/styles/products/visiva.css +1 -1
- package/package.json +4 -1
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { BlockData } from '@vigilkids/section-core'
|
|
3
|
+
|
|
4
|
+
import { computed } from 'vue'
|
|
5
|
+
|
|
6
|
+
import { useInlineEdit } from '../../../composables/useInlineEdit'
|
|
7
|
+
|
|
8
|
+
const props = defineProps<{
|
|
9
|
+
blockOrder: string[]
|
|
10
|
+
blocks: Record<string, BlockData>
|
|
11
|
+
editorMode?: boolean
|
|
12
|
+
settings: Record<string, unknown>
|
|
13
|
+
}>()
|
|
14
|
+
|
|
15
|
+
const emit = defineEmits<{
|
|
16
|
+
(e: 'update:setting', key: string, value: unknown): void
|
|
17
|
+
(e: 'update:block-setting', blockId: string, key: string, value: unknown): void
|
|
18
|
+
(e: 'inline-edit-start', key: string): void
|
|
19
|
+
(e: 'inline-edit-end'): void
|
|
20
|
+
(e: 'undo-redo', action: 'redo' | 'undo'): void
|
|
21
|
+
}>()
|
|
22
|
+
|
|
23
|
+
const s = computed(() => props.settings)
|
|
24
|
+
|
|
25
|
+
const variant = computed(() => String(s.value.variant || 'note'))
|
|
26
|
+
|
|
27
|
+
const containerClass = computed(() => {
|
|
28
|
+
if (variant.value === 'tips')
|
|
29
|
+
return 'tips-box'
|
|
30
|
+
if (variant.value === 'warning')
|
|
31
|
+
return 'note-box note-warning'
|
|
32
|
+
return 'note-box'
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
const labelClass = computed(() => (variant.value === 'tips' ? 'tips-box-label' : 'note-box-label'))
|
|
36
|
+
|
|
37
|
+
const contentClass = computed(() => (variant.value === 'tips' ? 'tips-box-content' : 'note-box-content'))
|
|
38
|
+
|
|
39
|
+
const { editableAttrs } = useInlineEdit({
|
|
40
|
+
editorMode: () => !!props.editorMode,
|
|
41
|
+
onSettingUpdate: (key, value) => emit('update:setting', key, value),
|
|
42
|
+
onBlockSettingUpdate: (blockId, key, value) => emit('update:block-setting', blockId, key, value),
|
|
43
|
+
onEditStart: key => emit('inline-edit-start', key),
|
|
44
|
+
onEditEnd: () => emit('inline-edit-end'),
|
|
45
|
+
onUndoRedo: action => emit('undo-redo', action),
|
|
46
|
+
})
|
|
47
|
+
</script>
|
|
48
|
+
|
|
49
|
+
<template>
|
|
50
|
+
<div :class="containerClass">
|
|
51
|
+
<div :class="labelClass">
|
|
52
|
+
<img v-if="s.icon_url" :src="(s.icon_url as string)" :alt="(s.label_text as string) || ''">
|
|
53
|
+
<span v-bind="editableAttrs('label_text')">{{ s.label_text }}</span>
|
|
54
|
+
</div>
|
|
55
|
+
<!-- eslint-disable-next-line vue/no-v-html -->
|
|
56
|
+
<p :class="contentClass" v-bind="editableAttrs('content')" v-html="s.content" />
|
|
57
|
+
</div>
|
|
58
|
+
</template>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { BlockData } from '@vigilkids/section-core';
|
|
2
|
+
type __VLS_Props = {
|
|
3
|
+
blockOrder: string[];
|
|
4
|
+
blocks: Record<string, BlockData>;
|
|
5
|
+
editorMode?: boolean;
|
|
6
|
+
settings: Record<string, unknown>;
|
|
7
|
+
};
|
|
8
|
+
declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
9
|
+
"update:setting": (key: string, value: unknown) => any;
|
|
10
|
+
"update:block-setting": (blockId: string, key: string, value: unknown) => any;
|
|
11
|
+
"inline-edit-start": (key: string) => any;
|
|
12
|
+
"inline-edit-end": () => any;
|
|
13
|
+
"undo-redo": (action: "redo" | "undo") => any;
|
|
14
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
15
|
+
"onUpdate:setting"?: ((key: string, value: unknown) => any) | undefined;
|
|
16
|
+
"onUpdate:block-setting"?: ((blockId: string, key: string, value: unknown) => any) | undefined;
|
|
17
|
+
"onInline-edit-start"?: ((key: string) => any) | undefined;
|
|
18
|
+
"onInline-edit-end"?: (() => any) | undefined;
|
|
19
|
+
"onUndo-redo"?: ((action: "redo" | "undo") => any) | undefined;
|
|
20
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
21
|
+
export default _default;
|
|
@@ -28,7 +28,13 @@ const emit = defineEmits<{
|
|
|
28
28
|
(e: 'undo-redo', action: 'redo' | 'undo'): void
|
|
29
29
|
}>()
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
// 标题允许富文本(例如带 <b>);空值时回退默认文案
|
|
32
|
+
const title = computed(() => {
|
|
33
|
+
const raw = props.settings.title
|
|
34
|
+
if (typeof raw === 'string' && raw.trim() !== '')
|
|
35
|
+
return raw
|
|
36
|
+
return 'Table Of Contents'
|
|
37
|
+
})
|
|
32
38
|
|
|
33
39
|
// 将 blockOrder 中连续的 toc-h3 归组到前一个 toc-h2 下
|
|
34
40
|
const tocGroups = computed<TocGroup[]>(() => {
|
|
@@ -63,7 +69,7 @@ const tocGroups = computed<TocGroup[]>(() => {
|
|
|
63
69
|
const hotIconSrc
|
|
64
70
|
= 'data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjAgMjAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTEwLjU0NzkgMTEuOTcwMkMxMC4wOTY2IDExLjk3MDIgOS43MTQ1NiAxMi41Mzg5IDkuNzE0NTYgMTMuMjE4OEM5LjcxNDU2IDEzLjg5NDggMTAuMDk2NiAxNC40NjY4IDEwLjU0NzkgMTQuNDY2OEMxMC45OTkyIDE0LjQ2NjggMTEuMzgxOSAxMy44OTY4IDExLjM4MTkgMTMuMjE3NUMxMS4zODE5IDEyLjUzODkgMTAuOTk5OSAxMS45Njg5IDEwLjU0ODUgMTEuOTY4OUwxMC41NDc5IDExLjk3MDJaTTE1LjM5NzcgMy41NDg0MUMxNS4zMjU4IDMuNDY4MTcgMTUuMjMzOCAzLjQwODQ4IDE1LjEzMTIgMy4zNzU0NUMxNS4wMjg2IDMuMzQyNDIgMTQuOTE5IDMuMzM3MjMgMTQuODEzOCAzLjM2MDQyQzE0LjYwMTggMy40MTEwOCAxNC40MjcxIDMuNTczNzQgMTQuMzQ3MSAzLjc5NTA3QzE0LjE2ODggNC4zMTgxNiAxNC4wMDM2IDQuODQ1NjUgMTMuODUxOCA1LjM3NzA0QzEzLjYzODUgNC45MzQzOCAxMy4zOTg1IDQuNTA5NzIgMTMuMTMxOCA0LjEwMzc0QzEyLjE0NzggMi42MDQ0NCAxMC43OTg1IDEuMzMxOCA4Ljg4NjU3IDAuMDk4NTAzN0M4Ljc5NTYgMC4wMzkxOTE2IDguNjkwMzIgMC4wMDU0NzcyOCA4LjU4MTgyIDAuMDAwOTAyOTA5QzguNDczMzEgLTAuMDAzNjcxNDYgOC4zNjU1OCAwLjAyMTA2MyA4LjI2OTkzIDAuMDcyNTA3NkM4LjE3MTE2IDAuMTI5NTgzIDguMDg3NjcgMC4yMDk3MjMgOC4wMjY2MSAwLjMwNjA3OUM3Ljk2NTU0IDAuNDAyNDM1IDcuOTI4NzEgMC41MTIxNDMgNy45MTkyNyAwLjYyNTgyOEM3LjY1MzI3IDMuMjI5NzMgNy4xNjM5NSA1Ljg2OTAxIDUuNDkyIDcuNzI2OTZMNS4yNzAwMSA3LjI1MzY0QzUuMDc0NyA2Ljg0NDMyIDQuODkyMDIgNi40NTkwMSA0Ljc3NDcgNi4xMjkwMUM0LjY0ODAyIDUuNzY1NjkgNC4yNzY3MSA1LjU4MzcgMy45NDUzOCA1LjcyMjM3QzMuNzkzMSA1Ljc4ODQ4IDMuNjcwOTMgNS45MDg5OCAzLjYwMjcyIDYuMDYwMzRMMy40NjgwNiA2LjM0N0MyLjY0NzQxIDguMDg2OTYgMS41MjU0NCAxMC40NzM2IDEuMzU2MSAxMi40OTE1QzEuMDA0NzcgMTYuNzY4NyA0LjU1NjY5IDE5LjQ1NjcgOC4yNTA1OSAxOS45MDMzQzkuMDYxOTIgMjAuMDAxMyA5Ljg3NzIyIDIwLjAyMzMgMTAuNjkxOSAxOS45NzMzQzEzLjU5NjUgMTkuNzg0IDE3LjEyNSAxOC4xNTU0IDE4LjMxNDMgMTQuMTQ2OEMxOS4wODQzIDExLjU0NDkgMTguNzgzNyA3LjIxMDMyIDE1LjM5NzcgMy41NDcwOFYzLjU0Nzc0VjMuNTQ4NDFaTTcuODI3OTQgMTUuMTUyMUM3LjgyNzk0IDE1LjQ5MDEgNy41NzUyOCAxNS43NjU1IDcuMjY0NjIgMTUuNzY1NUM2Ljk1NDY0IDE1Ljc2NjggNi43MDMyOSAxNS40OTIxIDYuNzAxOTYgMTUuMTUyMVYxMy43NTg4TDUuNTQyIDEzLjc3ODhWMTUuMTg2MUM1LjU0MiAxNS41MjM0IDUuMjg5MzQgMTUuNzk5NCA0Ljk3ODY4IDE1Ljc5OTRDNC42NjkzNiAxNS44MDA4IDQuNDE2NjkgMTUuNTI2MSA0LjQxNTM2IDE1LjE4NjFWMTEuNDE4OUM0LjQxNTM2IDExLjA4MDIgNC42NjczNSAxMC44MDU2IDQuOTc4NjggMTAuODA1NkM1LjI4OTM0IDEwLjgwNTYgNS41NDEzNCAxMS4wODAyIDUuNTQxMzQgMTEuNDE4OVYxMi41NTE1TDYuNzAxOTYgMTIuNTMyMlYxMS4zODU1QzYuNzAxOTYgMTEuMDQ2OSA2Ljk1Mzk1IDEwLjc3MTYgNy4yNjQ2MiAxMC43NzE2QzcuNTc1MjggMTAuNzcxNiA3LjgyNzI3IDExLjA0NjkgNy44MjcyNyAxMS4zODQ5VjE1LjE1MTVINy44Mjc5NFYxNS4xNTIxWk0xMC41NDc5IDE1LjY5MDhDOS40Njc5IDE1LjY5MDggOC41OTA1OSAxNC41ODAxIDguNTkwNTkgMTMuMjE1NUM4LjU5MDU5IDExLjg1MDkgOS40Njc5IDEwLjc0MDIgMTAuNTQ3OSAxMC43NDAyQzExLjYyNzggMTAuNzQwMiAxMi41MDc4IDExLjg1MDkgMTIuNTA3OCAxMy4yMTU1QzEyLjUwNjUgMTQuNTgwMSAxMS42Mjc4IDE1LjY5MDggMTAuNTQ3OSAxNS42OTA4VjE1LjY5MDhaTTE1LjY1MDQgMTIuMTAyMkgxNC45MzUxVjE1LjExODhDMTQuOTM1MSAxNS40NTY4IDE0LjY4MzggMTUuNzMyMSAxNC4zNzMxIDE1LjczMjFDMTQuMDYzMSAxNS43MzM0IDEzLjgxMTEgMTUuNDU4OCAxMy44MDkxIDE1LjExODhWMTIuMTAyMkgxMy4wOTUxQzEzLjAyMDIgMTIuMTAyMiAxMi45NDYxIDEyLjA4NjIgMTIuODc3OCAxMi4wNTUzQzEyLjgwOTUgMTIuMDI0NCAxMi43NDg2IDExLjk3OTIgMTIuNjk5MSAxMS45MjI5QzEyLjU5MzEgMTEuODAyMyAxMi41MzM5IDExLjY0NzUgMTIuNTMyNSAxMS40ODY5QzEyLjUzMjUgMTEuMTQ4MiAxMi43ODQ1IDEwLjg3MzYgMTMuMDk1MSAxMC44NzM2SDE1LjY0ODRDMTUuOTU5MSAxMC44NzM2IDE2LjIxMDQgMTEuMTQ4MiAxNi4yMTA0IDExLjQ4NjlDMTYuMjA5OSAxMS42NDc3IDE2LjE1MDYgMTEuODAyOCAxNi4wNDM3IDExLjkyMjlDMTUuOTk1MSAxMS45Nzk2IDE1LjkzNDggMTIuMDI1MSAxNS44NjY5IDEyLjA1NjJDMTUuNzk5IDEyLjA4NzIgMTUuNzI1MSAxMi4xMDMyIDE1LjY1MDQgMTIuMTAyOVYxMi4xMDIyWiIgZmlsbD0iI0Y3NDM0MyIvPjwvc3ZnPg=='
|
|
65
71
|
|
|
66
|
-
const { editableAttrs } = useInlineEdit({
|
|
72
|
+
const { editableAttrs, blockEditableAttrs } = useInlineEdit({
|
|
67
73
|
editorMode: () => !!props.editorMode,
|
|
68
74
|
onSettingUpdate: (key, value) => emit('update:setting', key, value),
|
|
69
75
|
onBlockSettingUpdate: (blockId, key, value) => emit('update:block-setting', blockId, key, value),
|
|
@@ -75,13 +81,17 @@ const { editableAttrs } = useInlineEdit({
|
|
|
75
81
|
|
|
76
82
|
<template>
|
|
77
83
|
<ul class="level-1">
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
84
|
+
<!-- eslint-disable-next-line vue/no-v-html -->
|
|
85
|
+
<li
|
|
86
|
+
class="table-of-contents"
|
|
87
|
+
v-bind="editableAttrs('title')"
|
|
88
|
+
v-html="title"
|
|
89
|
+
/>
|
|
81
90
|
<template v-for="group in tocGroups" :key="group.id">
|
|
82
91
|
<li :class="{ 'hot-link': group.hot }">
|
|
83
92
|
<a :href="`#${group.anchor}`">
|
|
84
|
-
|
|
93
|
+
<!-- eslint-disable-next-line vue/no-v-html -->
|
|
94
|
+
<span v-bind="blockEditableAttrs(group.id, 'text')" v-html="group.text" />
|
|
85
95
|
<img
|
|
86
96
|
v-if="group.hot"
|
|
87
97
|
class="hot-icon"
|
|
@@ -94,7 +104,12 @@ const { editableAttrs } = useInlineEdit({
|
|
|
94
104
|
</li>
|
|
95
105
|
<ul v-if="group.children.length > 0" class="level-2">
|
|
96
106
|
<li v-for="child in group.children" :key="child.id">
|
|
97
|
-
|
|
107
|
+
<!-- eslint-disable-next-line vue/no-v-html -->
|
|
108
|
+
<a
|
|
109
|
+
:href="`#${child.anchor}`"
|
|
110
|
+
v-bind="blockEditableAttrs(child.id, 'text')"
|
|
111
|
+
v-html="child.text"
|
|
112
|
+
/>
|
|
98
113
|
</li>
|
|
99
114
|
</ul>
|
|
100
115
|
</template>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { BlockData } from '@vigilkids/section-core';
|
|
2
|
+
type __VLS_Props = {
|
|
3
|
+
blockOrder: string[];
|
|
4
|
+
blocks: Record<string, BlockData>;
|
|
5
|
+
editorMode?: boolean;
|
|
6
|
+
settings: Record<string, unknown>;
|
|
7
|
+
};
|
|
8
|
+
declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
9
|
+
"update:setting": (key: string, value: unknown) => any;
|
|
10
|
+
"update:block-setting": (blockId: string, key: string, value: unknown) => any;
|
|
11
|
+
"inline-edit-start": (key: string) => any;
|
|
12
|
+
"inline-edit-end": () => any;
|
|
13
|
+
"undo-redo": (action: "redo" | "undo") => any;
|
|
14
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
15
|
+
"onUpdate:setting"?: ((key: string, value: unknown) => any) | undefined;
|
|
16
|
+
"onUpdate:block-setting"?: ((blockId: string, key: string, value: unknown) => any) | undefined;
|
|
17
|
+
"onInline-edit-start"?: ((key: string) => any) | undefined;
|
|
18
|
+
"onInline-edit-end"?: (() => any) | undefined;
|
|
19
|
+
"onUndo-redo"?: ((action: "redo" | "undo") => any) | undefined;
|
|
20
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
21
|
+
export default _default;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { BlockData } from '@vigilkids/section-core'
|
|
3
|
+
|
|
4
|
+
import { computed } from 'vue'
|
|
5
|
+
|
|
6
|
+
import { useInlineEdit } from '../../../composables/useInlineEdit'
|
|
7
|
+
|
|
8
|
+
const props = defineProps<{
|
|
9
|
+
blockOrder: string[]
|
|
10
|
+
blocks: Record<string, BlockData>
|
|
11
|
+
editorMode?: boolean
|
|
12
|
+
settings: Record<string, unknown>
|
|
13
|
+
}>()
|
|
14
|
+
|
|
15
|
+
const emit = defineEmits<{
|
|
16
|
+
(e: 'update:setting', key: string, value: unknown): void
|
|
17
|
+
(e: 'update:block-setting', blockId: string, key: string, value: unknown): void
|
|
18
|
+
(e: 'inline-edit-start', key: string): void
|
|
19
|
+
(e: 'inline-edit-end'): void
|
|
20
|
+
(e: 'undo-redo', action: 'redo' | 'undo'): void
|
|
21
|
+
}>()
|
|
22
|
+
|
|
23
|
+
const s = computed(() => props.settings)
|
|
24
|
+
|
|
25
|
+
const variant = computed(() => String(s.value.variant || 'dot'))
|
|
26
|
+
|
|
27
|
+
const listClass = computed(() => `toc-list-${variant.value}`)
|
|
28
|
+
|
|
29
|
+
const isOrdered = computed(() => variant.value === 'ordered')
|
|
30
|
+
|
|
31
|
+
const items = computed(() =>
|
|
32
|
+
props.blockOrder
|
|
33
|
+
.filter(id => props.blocks[id]?.type === 'toc_item')
|
|
34
|
+
.map(id => ({ id, block: props.blocks[id]! })),
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
const { blockEditableAttrs } = useInlineEdit({
|
|
38
|
+
editorMode: () => !!props.editorMode,
|
|
39
|
+
onSettingUpdate: (key, value) => emit('update:setting', key, value),
|
|
40
|
+
onBlockSettingUpdate: (blockId, key, value) => emit('update:block-setting', blockId, key, value),
|
|
41
|
+
onEditStart: key => emit('inline-edit-start', key),
|
|
42
|
+
onEditEnd: () => emit('inline-edit-end'),
|
|
43
|
+
onUndoRedo: action => emit('undo-redo', action),
|
|
44
|
+
})
|
|
45
|
+
</script>
|
|
46
|
+
|
|
47
|
+
<template>
|
|
48
|
+
<ol v-if="isOrdered" :class="listClass">
|
|
49
|
+
<!-- eslint-disable-next-line vue/no-v-html -->
|
|
50
|
+
<li v-for="item in items" :key="item.id" v-bind="blockEditableAttrs(item.id, 'text')" v-html="item.block.settings.text" />
|
|
51
|
+
</ol>
|
|
52
|
+
<ul v-else :class="listClass">
|
|
53
|
+
<!-- eslint-disable-next-line vue/no-v-html -->
|
|
54
|
+
<li v-for="item in items" :key="item.id" v-bind="blockEditableAttrs(item.id, 'text')" v-html="item.block.settings.text" />
|
|
55
|
+
</ul>
|
|
56
|
+
</template>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { BlockData } from '@vigilkids/section-core';
|
|
2
|
+
type __VLS_Props = {
|
|
3
|
+
blockOrder: string[];
|
|
4
|
+
blocks: Record<string, BlockData>;
|
|
5
|
+
editorMode?: boolean;
|
|
6
|
+
settings: Record<string, unknown>;
|
|
7
|
+
};
|
|
8
|
+
declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
9
|
+
"update:setting": (key: string, value: unknown) => any;
|
|
10
|
+
"update:block-setting": (blockId: string, key: string, value: unknown) => any;
|
|
11
|
+
"inline-edit-start": (key: string) => any;
|
|
12
|
+
"inline-edit-end": () => any;
|
|
13
|
+
"undo-redo": (action: "redo" | "undo") => any;
|
|
14
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
15
|
+
"onUpdate:setting"?: ((key: string, value: unknown) => any) | undefined;
|
|
16
|
+
"onUpdate:block-setting"?: ((blockId: string, key: string, value: unknown) => any) | undefined;
|
|
17
|
+
"onInline-edit-start"?: ((key: string) => any) | undefined;
|
|
18
|
+
"onInline-edit-end"?: (() => any) | undefined;
|
|
19
|
+
"onUndo-redo"?: ((action: "redo" | "undo") => any) | undefined;
|
|
20
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
21
|
+
export default _default;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { BlockData } from '@vigilkids/section-core';
|
|
2
|
+
type __VLS_Props = {
|
|
3
|
+
blockOrder: string[];
|
|
4
|
+
blocks: Record<string, BlockData>;
|
|
5
|
+
editorMode?: boolean;
|
|
6
|
+
settings: Record<string, unknown>;
|
|
7
|
+
};
|
|
8
|
+
declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
9
|
+
"update:setting": (key: string, value: unknown) => any;
|
|
10
|
+
"update:block-setting": (blockId: string, key: string, value: unknown) => any;
|
|
11
|
+
"inline-edit-start": (key: string) => any;
|
|
12
|
+
"inline-edit-end": () => any;
|
|
13
|
+
"undo-redo": (action: "redo" | "undo") => any;
|
|
14
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
15
|
+
"onUpdate:setting"?: ((key: string, value: unknown) => any) | undefined;
|
|
16
|
+
"onUpdate:block-setting"?: ((blockId: string, key: string, value: unknown) => any) | undefined;
|
|
17
|
+
"onInline-edit-start"?: ((key: string) => any) | undefined;
|
|
18
|
+
"onInline-edit-end"?: (() => any) | undefined;
|
|
19
|
+
"onUndo-redo"?: ((action: "redo" | "undo") => any) | undefined;
|
|
20
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
21
|
+
export default _default;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { BlockData } from '@vigilkids/section-core'
|
|
3
|
+
|
|
4
|
+
import { computed } from 'vue'
|
|
5
|
+
|
|
6
|
+
import { useInlineEdit } from '../../../composables/useInlineEdit'
|
|
7
|
+
|
|
8
|
+
const props = defineProps<{
|
|
9
|
+
blockOrder: string[]
|
|
10
|
+
blocks: Record<string, BlockData>
|
|
11
|
+
editorMode?: boolean
|
|
12
|
+
settings: Record<string, unknown>
|
|
13
|
+
}>()
|
|
14
|
+
|
|
15
|
+
const emit = defineEmits<{
|
|
16
|
+
(e: 'update:setting', key: string, value: unknown): void
|
|
17
|
+
(e: 'update:block-setting', blockId: string, key: string, value: unknown): void
|
|
18
|
+
(e: 'inline-edit-start', key: string): void
|
|
19
|
+
(e: 'inline-edit-end'): void
|
|
20
|
+
(e: 'undo-redo', action: 'redo' | 'undo'): void
|
|
21
|
+
}>()
|
|
22
|
+
|
|
23
|
+
const s = computed(() => props.settings)
|
|
24
|
+
|
|
25
|
+
const features = computed(() =>
|
|
26
|
+
props.blockOrder
|
|
27
|
+
.filter(id => props.blocks[id]?.type === 'feature')
|
|
28
|
+
.map(id => ({ id, block: props.blocks[id]! })),
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
const { editableAttrs, blockEditableAttrs } = useInlineEdit({
|
|
32
|
+
editorMode: () => !!props.editorMode,
|
|
33
|
+
onSettingUpdate: (key, value) => emit('update:setting', key, value),
|
|
34
|
+
onBlockSettingUpdate: (blockId, key, value) => emit('update:block-setting', blockId, key, value),
|
|
35
|
+
onEditStart: key => emit('inline-edit-start', key),
|
|
36
|
+
onEditEnd: () => emit('inline-edit-end'),
|
|
37
|
+
onUndoRedo: action => emit('undo-redo', action),
|
|
38
|
+
})
|
|
39
|
+
</script>
|
|
40
|
+
|
|
41
|
+
<template>
|
|
42
|
+
<section class="top-banner">
|
|
43
|
+
<div class="top-banner-info">
|
|
44
|
+
<img
|
|
45
|
+
v-if="s.header_image_url"
|
|
46
|
+
class="top-banner-header"
|
|
47
|
+
:src="(s.header_image_url as string)"
|
|
48
|
+
:alt="(s.header_alt as string) || ''"
|
|
49
|
+
>
|
|
50
|
+
<!-- eslint-disable-next-line vue/no-v-html -->
|
|
51
|
+
<p
|
|
52
|
+
v-if="s.description"
|
|
53
|
+
class="top-banner-desc"
|
|
54
|
+
v-bind="editableAttrs('description')"
|
|
55
|
+
v-html="s.description"
|
|
56
|
+
/>
|
|
57
|
+
<ul v-if="features.length" class="top-banner-features">
|
|
58
|
+
<!-- eslint-disable-next-line vue/no-v-html -->
|
|
59
|
+
<li
|
|
60
|
+
v-for="item in features"
|
|
61
|
+
:key="item.id"
|
|
62
|
+
v-bind="blockEditableAttrs(item.id, 'text')"
|
|
63
|
+
v-html="item.block.settings.text"
|
|
64
|
+
/>
|
|
65
|
+
</ul>
|
|
66
|
+
<a
|
|
67
|
+
v-if="s.cta_primary_label"
|
|
68
|
+
class="top-banner-btn-primary"
|
|
69
|
+
:href="(s.cta_primary_url as string) || '#'"
|
|
70
|
+
v-bind="editableAttrs('cta_primary_label')"
|
|
71
|
+
>
|
|
72
|
+
{{ s.cta_primary_label }}
|
|
73
|
+
</a>
|
|
74
|
+
<a
|
|
75
|
+
v-if="s.cta_outline_label"
|
|
76
|
+
class="top-banner-btn-outline"
|
|
77
|
+
:href="(s.cta_outline_url as string) || '#'"
|
|
78
|
+
v-bind="editableAttrs('cta_outline_label')"
|
|
79
|
+
>
|
|
80
|
+
{{ s.cta_outline_label }}
|
|
81
|
+
</a>
|
|
82
|
+
</div>
|
|
83
|
+
<img
|
|
84
|
+
v-if="s.mockup_image_url"
|
|
85
|
+
class="top-banner-mockup"
|
|
86
|
+
:src="(s.mockup_image_url as string)"
|
|
87
|
+
:alt="(s.mockup_alt as string) || ''"
|
|
88
|
+
>
|
|
89
|
+
</section>
|
|
90
|
+
</template>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { BlockData } from '@vigilkids/section-core';
|
|
2
|
+
type __VLS_Props = {
|
|
3
|
+
blockOrder: string[];
|
|
4
|
+
blocks: Record<string, BlockData>;
|
|
5
|
+
editorMode?: boolean;
|
|
6
|
+
settings: Record<string, unknown>;
|
|
7
|
+
};
|
|
8
|
+
declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
9
|
+
"update:setting": (key: string, value: unknown) => any;
|
|
10
|
+
"update:block-setting": (blockId: string, key: string, value: unknown) => any;
|
|
11
|
+
"inline-edit-start": (key: string) => any;
|
|
12
|
+
"inline-edit-end": () => any;
|
|
13
|
+
"undo-redo": (action: "redo" | "undo") => any;
|
|
14
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
15
|
+
"onUpdate:setting"?: ((key: string, value: unknown) => any) | undefined;
|
|
16
|
+
"onUpdate:block-setting"?: ((blockId: string, key: string, value: unknown) => any) | undefined;
|
|
17
|
+
"onInline-edit-start"?: ((key: string) => any) | undefined;
|
|
18
|
+
"onInline-edit-end"?: (() => any) | undefined;
|
|
19
|
+
"onUndo-redo"?: ((action: "redo" | "undo") => any) | undefined;
|
|
20
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
21
|
+
export default _default;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
type __VLS_Props = {
|
|
2
|
+
s: Record<string, unknown>;
|
|
3
|
+
editableAttrs: (settingKey: string) => Record<string, unknown>;
|
|
4
|
+
};
|
|
5
|
+
declare const _default: 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
|
+
export default _default;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
// CTA 按钮组:7 个 variant 共用同一套主/次按钮 DOM 结构
|
|
3
|
+
// 通过 props 接收 settings 和 editableAttrs(由父组件内的 useInlineEdit 生成)
|
|
4
|
+
// 拆出此组件是为了消除 v-if 链中的 CTA 重复(原文件有 7 次相同的 action-buttons 块)
|
|
5
|
+
const props = defineProps<{
|
|
6
|
+
s: Record<string, unknown>
|
|
7
|
+
editableAttrs: (settingKey: string) => Record<string, unknown>
|
|
8
|
+
}>()
|
|
9
|
+
|
|
10
|
+
// 解构响应式数据仅用于模板引用简写,不破坏 props 响应性(props 本身是 reactive)
|
|
11
|
+
const { s, editableAttrs } = props
|
|
12
|
+
</script>
|
|
13
|
+
|
|
14
|
+
<template>
|
|
15
|
+
<div class="action-buttons">
|
|
16
|
+
<!-- eslint-disable-next-line vue/no-v-html -->
|
|
17
|
+
<a :href="(s.cta_primary_url as string) || '#'" class="article-btn-primary" v-bind="editableAttrs('cta_primary_label')" v-html="s.cta_primary_label" />
|
|
18
|
+
<!-- eslint-disable-next-line vue/no-v-html -->
|
|
19
|
+
<a :href="(s.cta_outline_url as string) || '#'" class="article-btn-outline" v-bind="editableAttrs('cta_outline_label')" v-html="s.cta_outline_label" />
|
|
20
|
+
</div>
|
|
21
|
+
</template>
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
type __VLS_Props = {
|
|
2
|
+
s: Record<string, unknown>;
|
|
3
|
+
editableAttrs: (settingKey: string) => Record<string, unknown>;
|
|
4
|
+
};
|
|
5
|
+
declare const _default: 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
|
+
export default _default;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { BlockData } from '@vigilkids/section-core';
|
|
2
|
+
type __VLS_Props = {
|
|
3
|
+
blockOrder: string[];
|
|
4
|
+
blocks: Record<string, BlockData>;
|
|
5
|
+
editorMode?: boolean;
|
|
6
|
+
settings: Record<string, unknown>;
|
|
7
|
+
};
|
|
8
|
+
declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
9
|
+
"update:setting": (key: string, value: unknown) => any;
|
|
10
|
+
"update:block-setting": (blockId: string, key: string, value: unknown) => any;
|
|
11
|
+
"inline-edit-start": (key: string) => any;
|
|
12
|
+
"inline-edit-end": () => any;
|
|
13
|
+
"undo-redo": (action: "redo" | "undo") => any;
|
|
14
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
15
|
+
"onUpdate:setting"?: ((key: string, value: unknown) => any) | undefined;
|
|
16
|
+
"onUpdate:block-setting"?: ((blockId: string, key: string, value: unknown) => any) | undefined;
|
|
17
|
+
"onInline-edit-start"?: ((key: string) => any) | undefined;
|
|
18
|
+
"onInline-edit-end"?: (() => any) | undefined;
|
|
19
|
+
"onUndo-redo"?: ((action: "redo" | "undo") => any) | undefined;
|
|
20
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
21
|
+
export default _default;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { BlockData } from '@vigilkids/section-core'
|
|
3
|
+
|
|
4
|
+
import { computed } from 'vue'
|
|
5
|
+
|
|
6
|
+
import { useInlineEdit } from '../../../../composables/useInlineEdit'
|
|
7
|
+
import ProductCardCtaGroup from './ProductCardCtaGroup.vue'
|
|
8
|
+
|
|
9
|
+
// Variant A: 无图,标准型(product-card)
|
|
10
|
+
// 契约与主组件对齐:每个 variant 独立完整 emit + useInlineEdit,保证可单独测试/替换
|
|
11
|
+
const props = defineProps<{
|
|
12
|
+
blockOrder: string[]
|
|
13
|
+
blocks: Record<string, BlockData>
|
|
14
|
+
editorMode?: boolean
|
|
15
|
+
settings: Record<string, unknown>
|
|
16
|
+
}>()
|
|
17
|
+
|
|
18
|
+
const emit = defineEmits<{
|
|
19
|
+
(e: 'update:setting', key: string, value: unknown): void
|
|
20
|
+
(e: 'update:block-setting', blockId: string, key: string, value: unknown): void
|
|
21
|
+
(e: 'inline-edit-start', key: string): void
|
|
22
|
+
(e: 'inline-edit-end'): void
|
|
23
|
+
(e: 'undo-redo', action: 'redo' | 'undo'): void
|
|
24
|
+
}>()
|
|
25
|
+
|
|
26
|
+
const s = computed(() => props.settings)
|
|
27
|
+
|
|
28
|
+
const { editableAttrs } = useInlineEdit({
|
|
29
|
+
editorMode: () => !!props.editorMode,
|
|
30
|
+
onSettingUpdate: (key, value) => emit('update:setting', key, value),
|
|
31
|
+
onBlockSettingUpdate: (blockId, key, value) => emit('update:block-setting', blockId, key, value),
|
|
32
|
+
onEditStart: key => emit('inline-edit-start', key),
|
|
33
|
+
onEditEnd: () => emit('inline-edit-end'),
|
|
34
|
+
onUndoRedo: action => emit('undo-redo', action),
|
|
35
|
+
})
|
|
36
|
+
</script>
|
|
37
|
+
|
|
38
|
+
<template>
|
|
39
|
+
<div class="product-card-content">
|
|
40
|
+
<!-- eslint-disable-next-line vue/no-v-html -->
|
|
41
|
+
<p class="product-name" v-bind="editableAttrs('product_name')" v-html="s.product_name" />
|
|
42
|
+
<!-- eslint-disable-next-line vue/no-v-html -->
|
|
43
|
+
<p class="product-desc" v-bind="editableAttrs('product_desc')" v-html="s.product_desc" />
|
|
44
|
+
</div>
|
|
45
|
+
<ProductCardCtaGroup :s="s" :editable-attrs="editableAttrs" />
|
|
46
|
+
</template>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { BlockData } from '@vigilkids/section-core';
|
|
2
|
+
type __VLS_Props = {
|
|
3
|
+
blockOrder: string[];
|
|
4
|
+
blocks: Record<string, BlockData>;
|
|
5
|
+
editorMode?: boolean;
|
|
6
|
+
settings: Record<string, unknown>;
|
|
7
|
+
};
|
|
8
|
+
declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
9
|
+
"update:setting": (key: string, value: unknown) => any;
|
|
10
|
+
"update:block-setting": (blockId: string, key: string, value: unknown) => any;
|
|
11
|
+
"inline-edit-start": (key: string) => any;
|
|
12
|
+
"inline-edit-end": () => any;
|
|
13
|
+
"undo-redo": (action: "redo" | "undo") => any;
|
|
14
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
15
|
+
"onUpdate:setting"?: ((key: string, value: unknown) => any) | undefined;
|
|
16
|
+
"onUpdate:block-setting"?: ((blockId: string, key: string, value: unknown) => any) | undefined;
|
|
17
|
+
"onInline-edit-start"?: ((key: string) => any) | undefined;
|
|
18
|
+
"onInline-edit-end"?: (() => any) | undefined;
|
|
19
|
+
"onUndo-redo"?: ((action: "redo" | "undo") => any) | undefined;
|
|
20
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
21
|
+
export default _default;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { BlockData } from '@vigilkids/section-core';
|
|
2
|
+
type __VLS_Props = {
|
|
3
|
+
blockOrder: string[];
|
|
4
|
+
blocks: Record<string, BlockData>;
|
|
5
|
+
editorMode?: boolean;
|
|
6
|
+
settings: Record<string, unknown>;
|
|
7
|
+
};
|
|
8
|
+
declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
9
|
+
"update:setting": (key: string, value: unknown) => any;
|
|
10
|
+
"update:block-setting": (blockId: string, key: string, value: unknown) => any;
|
|
11
|
+
"inline-edit-start": (key: string) => any;
|
|
12
|
+
"inline-edit-end": () => any;
|
|
13
|
+
"undo-redo": (action: "redo" | "undo") => any;
|
|
14
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
15
|
+
"onUpdate:setting"?: ((key: string, value: unknown) => any) | undefined;
|
|
16
|
+
"onUpdate:block-setting"?: ((blockId: string, key: string, value: unknown) => any) | undefined;
|
|
17
|
+
"onInline-edit-start"?: ((key: string) => any) | undefined;
|
|
18
|
+
"onInline-edit-end"?: (() => any) | undefined;
|
|
19
|
+
"onUndo-redo"?: ((action: "redo" | "undo") => any) | undefined;
|
|
20
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
21
|
+
export default _default;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { BlockData } from '@vigilkids/section-core'
|
|
3
|
+
|
|
4
|
+
import { computed } from 'vue'
|
|
5
|
+
|
|
6
|
+
import { useInlineEdit } from '../../../../composables/useInlineEdit'
|
|
7
|
+
import ProductCardCtaGroup from './ProductCardCtaGroup.vue'
|
|
8
|
+
|
|
9
|
+
// Variant B: 无图,紧凑型(product-card-compact)
|
|
10
|
+
// 与 Variant A 的 DOM 相同,区别仅在根 class(由主分发器提供),因此结构对齐
|
|
11
|
+
const props = defineProps<{
|
|
12
|
+
blockOrder: string[]
|
|
13
|
+
blocks: Record<string, BlockData>
|
|
14
|
+
editorMode?: boolean
|
|
15
|
+
settings: Record<string, unknown>
|
|
16
|
+
}>()
|
|
17
|
+
|
|
18
|
+
const emit = defineEmits<{
|
|
19
|
+
(e: 'update:setting', key: string, value: unknown): void
|
|
20
|
+
(e: 'update:block-setting', blockId: string, key: string, value: unknown): void
|
|
21
|
+
(e: 'inline-edit-start', key: string): void
|
|
22
|
+
(e: 'inline-edit-end'): void
|
|
23
|
+
(e: 'undo-redo', action: 'redo' | 'undo'): void
|
|
24
|
+
}>()
|
|
25
|
+
|
|
26
|
+
const s = computed(() => props.settings)
|
|
27
|
+
|
|
28
|
+
const { editableAttrs } = useInlineEdit({
|
|
29
|
+
editorMode: () => !!props.editorMode,
|
|
30
|
+
onSettingUpdate: (key, value) => emit('update:setting', key, value),
|
|
31
|
+
onBlockSettingUpdate: (blockId, key, value) => emit('update:block-setting', blockId, key, value),
|
|
32
|
+
onEditStart: key => emit('inline-edit-start', key),
|
|
33
|
+
onEditEnd: () => emit('inline-edit-end'),
|
|
34
|
+
onUndoRedo: action => emit('undo-redo', action),
|
|
35
|
+
})
|
|
36
|
+
</script>
|
|
37
|
+
|
|
38
|
+
<template>
|
|
39
|
+
<div class="product-card-content">
|
|
40
|
+
<!-- eslint-disable-next-line vue/no-v-html -->
|
|
41
|
+
<p class="product-name" v-bind="editableAttrs('product_name')" v-html="s.product_name" />
|
|
42
|
+
<!-- eslint-disable-next-line vue/no-v-html -->
|
|
43
|
+
<p class="product-desc" v-bind="editableAttrs('product_desc')" v-html="s.product_desc" />
|
|
44
|
+
</div>
|
|
45
|
+
<ProductCardCtaGroup :s="s" :editable-attrs="editableAttrs" />
|
|
46
|
+
</template>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { BlockData } from '@vigilkids/section-core';
|
|
2
|
+
type __VLS_Props = {
|
|
3
|
+
blockOrder: string[];
|
|
4
|
+
blocks: Record<string, BlockData>;
|
|
5
|
+
editorMode?: boolean;
|
|
6
|
+
settings: Record<string, unknown>;
|
|
7
|
+
};
|
|
8
|
+
declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
9
|
+
"update:setting": (key: string, value: unknown) => any;
|
|
10
|
+
"update:block-setting": (blockId: string, key: string, value: unknown) => any;
|
|
11
|
+
"inline-edit-start": (key: string) => any;
|
|
12
|
+
"inline-edit-end": () => any;
|
|
13
|
+
"undo-redo": (action: "redo" | "undo") => any;
|
|
14
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
15
|
+
"onUpdate:setting"?: ((key: string, value: unknown) => any) | undefined;
|
|
16
|
+
"onUpdate:block-setting"?: ((blockId: string, key: string, value: unknown) => any) | undefined;
|
|
17
|
+
"onInline-edit-start"?: ((key: string) => any) | undefined;
|
|
18
|
+
"onInline-edit-end"?: (() => any) | undefined;
|
|
19
|
+
"onUndo-redo"?: ((action: "redo" | "undo") => any) | undefined;
|
|
20
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
21
|
+
export default _default;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { BlockData } from '@vigilkids/section-core';
|
|
2
|
+
type __VLS_Props = {
|
|
3
|
+
blockOrder: string[];
|
|
4
|
+
blocks: Record<string, BlockData>;
|
|
5
|
+
editorMode?: boolean;
|
|
6
|
+
settings: Record<string, unknown>;
|
|
7
|
+
};
|
|
8
|
+
declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
9
|
+
"update:setting": (key: string, value: unknown) => any;
|
|
10
|
+
"update:block-setting": (blockId: string, key: string, value: unknown) => any;
|
|
11
|
+
"inline-edit-start": (key: string) => any;
|
|
12
|
+
"inline-edit-end": () => any;
|
|
13
|
+
"undo-redo": (action: "redo" | "undo") => any;
|
|
14
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
15
|
+
"onUpdate:setting"?: ((key: string, value: unknown) => any) | undefined;
|
|
16
|
+
"onUpdate:block-setting"?: ((blockId: string, key: string, value: unknown) => any) | undefined;
|
|
17
|
+
"onInline-edit-start"?: ((key: string) => any) | undefined;
|
|
18
|
+
"onInline-edit-end"?: (() => any) | undefined;
|
|
19
|
+
"onUndo-redo"?: ((action: "redo" | "undo") => any) | undefined;
|
|
20
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
21
|
+
export default _default;
|