@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.
Files changed (71) hide show
  1. package/dist/interactions/vigilkids.d.ts +44 -1
  2. package/dist/interactions/vigilkids.mjs +115 -1
  3. package/dist/sections/article/index.mjs +60 -0
  4. package/dist/sections/article/vigilkids/ArticleFaq.vue +9 -2
  5. package/dist/sections/article/vigilkids/ArticleFaqItem.d.vue.ts +3 -0
  6. package/dist/sections/article/vigilkids/ArticleFaqItem.vue +18 -18
  7. package/dist/sections/article/vigilkids/ArticleFaqItem.vue.d.ts +3 -0
  8. package/dist/sections/article/vigilkids/ArticleHeading.vue +2 -1
  9. package/dist/sections/article/vigilkids/ArticleHighlightParagraph.d.vue.ts +21 -0
  10. package/dist/sections/article/vigilkids/ArticleHighlightParagraph.vue +38 -0
  11. package/dist/sections/article/vigilkids/ArticleHighlightParagraph.vue.d.ts +21 -0
  12. package/dist/sections/article/vigilkids/ArticleProductCard.d.vue.ts +21 -0
  13. package/dist/sections/article/vigilkids/ArticleProductCard.vue +65 -0
  14. package/dist/sections/article/vigilkids/ArticleProductCard.vue.d.ts +21 -0
  15. package/dist/sections/article/vigilkids/ArticleProductInfoBanner.d.vue.ts +21 -0
  16. package/dist/sections/article/vigilkids/ArticleProductInfoBanner.vue +56 -0
  17. package/dist/sections/article/vigilkids/ArticleProductInfoBanner.vue.d.ts +21 -0
  18. package/dist/sections/article/vigilkids/ArticleRelatedArticles.d.vue.ts +21 -0
  19. package/dist/sections/article/vigilkids/ArticleRelatedArticles.vue +86 -0
  20. package/dist/sections/article/vigilkids/ArticleRelatedArticles.vue.d.ts +21 -0
  21. package/dist/sections/article/vigilkids/ArticleRetentionBanner.d.vue.ts +21 -0
  22. package/dist/sections/article/vigilkids/ArticleRetentionBanner.vue +100 -0
  23. package/dist/sections/article/vigilkids/ArticleRetentionBanner.vue.d.ts +21 -0
  24. package/dist/sections/article/vigilkids/ArticleSectionIntro.d.vue.ts +21 -0
  25. package/dist/sections/article/vigilkids/ArticleSectionIntro.vue +56 -0
  26. package/dist/sections/article/vigilkids/ArticleSectionIntro.vue.d.ts +21 -0
  27. package/dist/sections/article/vigilkids/ArticleStepList.vue +11 -6
  28. package/dist/sections/article/vigilkids/ArticleStyledHeading.d.vue.ts +21 -0
  29. package/dist/sections/article/vigilkids/ArticleStyledHeading.vue +48 -0
  30. package/dist/sections/article/vigilkids/ArticleStyledHeading.vue.d.ts +21 -0
  31. package/dist/sections/article/vigilkids/ArticleSubheading.vue +5 -4
  32. package/dist/sections/article/vigilkids/ArticleTable.d.vue.ts +13 -1
  33. package/dist/sections/article/vigilkids/ArticleTable.vue +26 -6
  34. package/dist/sections/article/vigilkids/ArticleTable.vue.d.ts +13 -1
  35. package/dist/sections/article/vigilkids/ArticleTipNote.d.vue.ts +21 -0
  36. package/dist/sections/article/vigilkids/ArticleTipNote.vue +58 -0
  37. package/dist/sections/article/vigilkids/ArticleTipNote.vue.d.ts +21 -0
  38. package/dist/sections/article/vigilkids/ArticleToc.vue +22 -7
  39. package/dist/sections/article/vigilkids/ArticleTocList.d.vue.ts +21 -0
  40. package/dist/sections/article/vigilkids/ArticleTocList.vue +56 -0
  41. package/dist/sections/article/vigilkids/ArticleTocList.vue.d.ts +21 -0
  42. package/dist/sections/article/vigilkids/ArticleTopAd.d.vue.ts +21 -0
  43. package/dist/sections/article/vigilkids/ArticleTopAd.vue +90 -0
  44. package/dist/sections/article/vigilkids/ArticleTopAd.vue.d.ts +21 -0
  45. package/dist/sections/article/vigilkids/product-card/ProductCardCtaGroup.d.vue.ts +6 -0
  46. package/dist/sections/article/vigilkids/product-card/ProductCardCtaGroup.vue +21 -0
  47. package/dist/sections/article/vigilkids/product-card/ProductCardCtaGroup.vue.d.ts +6 -0
  48. package/dist/sections/article/vigilkids/product-card/ProductCardVariantA.d.vue.ts +21 -0
  49. package/dist/sections/article/vigilkids/product-card/ProductCardVariantA.vue +46 -0
  50. package/dist/sections/article/vigilkids/product-card/ProductCardVariantA.vue.d.ts +21 -0
  51. package/dist/sections/article/vigilkids/product-card/ProductCardVariantB.d.vue.ts +21 -0
  52. package/dist/sections/article/vigilkids/product-card/ProductCardVariantB.vue +46 -0
  53. package/dist/sections/article/vigilkids/product-card/ProductCardVariantB.vue.d.ts +21 -0
  54. package/dist/sections/article/vigilkids/product-card/ProductCardVariantC.d.vue.ts +21 -0
  55. package/dist/sections/article/vigilkids/product-card/ProductCardVariantC.vue +46 -0
  56. package/dist/sections/article/vigilkids/product-card/ProductCardVariantC.vue.d.ts +21 -0
  57. package/dist/sections/article/vigilkids/product-card/ProductCardVariantD.d.vue.ts +21 -0
  58. package/dist/sections/article/vigilkids/product-card/ProductCardVariantD.vue +56 -0
  59. package/dist/sections/article/vigilkids/product-card/ProductCardVariantD.vue.d.ts +21 -0
  60. package/dist/sections/article/vigilkids/product-card/ProductCardVariantE.d.vue.ts +21 -0
  61. package/dist/sections/article/vigilkids/product-card/ProductCardVariantE.vue +55 -0
  62. package/dist/sections/article/vigilkids/product-card/ProductCardVariantE.vue.d.ts +21 -0
  63. package/dist/sections/article/vigilkids/product-card/ProductCardVariantF.d.vue.ts +21 -0
  64. package/dist/sections/article/vigilkids/product-card/ProductCardVariantF.vue +56 -0
  65. package/dist/sections/article/vigilkids/product-card/ProductCardVariantF.vue.d.ts +21 -0
  66. package/dist/sections/article/vigilkids/product-card/ProductCardVariantG.d.vue.ts +21 -0
  67. package/dist/sections/article/vigilkids/product-card/ProductCardVariantG.vue +52 -0
  68. package/dist/sections/article/vigilkids/product-card/ProductCardVariantG.vue.d.ts +21 -0
  69. package/dist/styles/products/vigilkids.css +1 -1
  70. package/dist/styles/products/visiva.css +1 -1
  71. package/package.json +4 -1
@@ -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,86 @@
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 items = computed(() =>
26
+ props.blockOrder
27
+ .filter(id => props.blocks[id]?.type === 'related_item')
28
+ .map(id => ({ id, block: props.blocks[id]! })),
29
+ )
30
+
31
+ const showDots = computed(() => !!s.value.show_dots)
32
+
33
+ const { editableAttrs, blockEditableAttrs } = useInlineEdit({
34
+ editorMode: () => !!props.editorMode,
35
+ onSettingUpdate: (key, value) => emit('update:setting', key, value),
36
+ onBlockSettingUpdate: (blockId, key, value) => emit('update:block-setting', blockId, key, value),
37
+ onEditStart: key => emit('inline-edit-start', key),
38
+ onEditEnd: () => emit('inline-edit-end'),
39
+ onUndoRedo: action => emit('undo-redo', action),
40
+ })
41
+ </script>
42
+
43
+ <template>
44
+ <section class="article-recommend" data-component="related-articles-carousel">
45
+ <h2 v-if="s.title" class="article-recommend-title" v-bind="editableAttrs('title')">
46
+ {{ s.title }}
47
+ </h2>
48
+ <div class="recommend-grid">
49
+ <a
50
+ v-for="(item, i) in items"
51
+ :key="item.id"
52
+ :href="(item.block.settings.url as string) || '#'"
53
+ class="recommend-card"
54
+ >
55
+ <div class="recommend-card-image">
56
+ <img
57
+ :src="(item.block.settings.image_url as string) || ''"
58
+ :alt="(item.block.settings.image_alt as string) || ''"
59
+ >
60
+ </div>
61
+ <!-- eslint-disable-next-line vue/no-v-html -->
62
+ <p
63
+ class="recommend-card-title"
64
+ v-bind="blockEditableAttrs(item.id, 'title')"
65
+ v-html="item.block.settings.title"
66
+ />
67
+ <!-- eslint-disable-next-line vue/no-v-html -->
68
+ <p
69
+ class="recommend-card-desc"
70
+ v-bind="blockEditableAttrs(item.id, 'description')"
71
+ v-html="item.block.settings.description"
72
+ />
73
+ <span class="sr-only">{{ i + 1 }}</span>
74
+ </a>
75
+ </div>
76
+ <div v-if="showDots && items.length > 0" class="recommend-dots">
77
+ <!-- 首屏先给第一个 dot 标 active 作为 init 前视觉提示;embla 初始化后由 interactions/vigilkids.ts 的 syncActive 接管 -->
78
+ <span
79
+ v-for="(item, i) in items"
80
+ :key="item.id"
81
+ class="recommend-dot"
82
+ :class="{ active: i === 0 }"
83
+ />
84
+ </div>
85
+ </section>
86
+ </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,100 @@
1
+ <script setup lang="ts">
2
+ import type { BlockData } from '@vigilkids/section-core'
3
+
4
+ import { computed, onMounted, ref } 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
+ const dismissKey = computed(() => (s.value.dismiss_key as string) || '')
25
+ // dismissKey 为空时也允许关闭,只是本次会话内关闭不持久化
26
+ const storageKey = computed(() => (dismissKey.value ? `retention-banner-dismissed:${dismissKey.value}` : ''))
27
+
28
+ const dismissed = ref(false)
29
+
30
+ // 初始挂载时读取持久化状态;editorMode 下跳过以方便运营预览样式
31
+ onMounted(() => {
32
+ if (props.editorMode)
33
+ return
34
+ if (storageKey.value && typeof localStorage !== 'undefined' && localStorage.getItem(storageKey.value)) {
35
+ dismissed.value = true
36
+ }
37
+ })
38
+
39
+ function handleClose() {
40
+ if (storageKey.value && typeof localStorage !== 'undefined') {
41
+ localStorage.setItem(storageKey.value, '1')
42
+ }
43
+ dismissed.value = true
44
+ }
45
+
46
+ const { editableAttrs } = useInlineEdit({
47
+ editorMode: () => !!props.editorMode,
48
+ onSettingUpdate: (key, value) => emit('update:setting', key, value),
49
+ onBlockSettingUpdate: (blockId, key, value) => emit('update:block-setting', blockId, key, value),
50
+ onEditStart: key => emit('inline-edit-start', key),
51
+ onEditEnd: () => emit('inline-edit-end'),
52
+ onUndoRedo: action => emit('undo-redo', action),
53
+ })
54
+ </script>
55
+
56
+ <template>
57
+ <section v-if="!dismissed">
58
+ <div
59
+ class="retention-banner"
60
+ data-component="retention-banner"
61
+ :data-dismiss-key="dismissKey"
62
+ >
63
+ <div class="retention-banner-inner">
64
+ <img
65
+ class="retention-banner-img"
66
+ :src="(s.image_url as string) || ''"
67
+ :alt="(s.image_alt as string) || ''"
68
+ >
69
+ <div>
70
+ <p class="retention-banner-text">
71
+ <!-- eslint-disable-next-line vue/no-v-html -->
72
+ <span v-bind="editableAttrs('text_prefix')" v-html="s.text_prefix" />
73
+ <!-- eslint-disable-next-line vue/no-v-html -->
74
+ <span class="retention-highlight" v-bind="editableAttrs('highlight_text')" v-html="s.highlight_text" />
75
+ <!-- eslint-disable-next-line vue/no-v-html -->
76
+ <span v-bind="editableAttrs('text_suffix')" v-html="s.text_suffix" />
77
+ </p>
78
+ <a
79
+ v-if="s.cta_label"
80
+ class="retention-banner-btn"
81
+ :href="(s.cta_url as string) || '#'"
82
+ v-bind="editableAttrs('cta_label')"
83
+ >
84
+ {{ s.cta_label }}
85
+ </a>
86
+ </div>
87
+ </div>
88
+ <button
89
+ type="button"
90
+ class="retention-banner-close"
91
+ aria-label="Close"
92
+ @click.stop="handleClose"
93
+ >
94
+ <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
95
+ <path d="M4 4L12 12M12 4L4 12" stroke="#000" stroke-width="1.5" stroke-linecap="round" />
96
+ </svg>
97
+ </button>
98
+ </div>
99
+ </section>
100
+ </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,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 items = computed(() =>
26
+ props.blockOrder
27
+ .filter(id => props.blocks[id]?.type === 'intro_item')
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>
43
+ <p class="section-intro">
44
+ <!-- eslint-disable-next-line vue/no-v-html -->
45
+ <span class="section-intro-bold" v-bind="editableAttrs('bold_text')" v-html="s.bold_text" />
46
+ <!-- eslint-disable-next-line vue/no-v-html -->
47
+ <span v-bind="editableAttrs('intro_text')" v-html="s.intro_text" />
48
+ </p>
49
+ <ul class="section-intro-list">
50
+ <li v-for="item in items" :key="item.id">
51
+ <!-- eslint-disable-next-line vue/no-v-html -->
52
+ <span v-bind="blockEditableAttrs(item.id, 'text')" v-html="item.block.settings.text" />
53
+ </li>
54
+ </ul>
55
+ </section>
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;
@@ -37,12 +37,17 @@ const { blockEditableAttrs } = useInlineEdit({
37
37
  <ul class="step-list">
38
38
  <template v-for="blockId in blockOrder" :key="blockId">
39
39
  <li v-if="blocks[blockId]">
40
- <span class="primary-color" v-bind="blockEditableAttrs(blockId, 'label')">{{
41
- blocks[blockId]!.settings.label
42
- }}</span>
43
- <span v-bind="blockEditableAttrs(blockId, 'description')">{{
44
- blocks[blockId]!.settings.description
45
- }}</span>
40
+ <!-- eslint-disable-next-line vue/no-v-html -->
41
+ <span
42
+ class="primary-color"
43
+ v-bind="blockEditableAttrs(blockId, 'label')"
44
+ v-html="blocks[blockId]!.settings.label"
45
+ />
46
+ <!-- eslint-disable-next-line vue/no-v-html -->
47
+ <span
48
+ v-bind="blockEditableAttrs(blockId, 'description')"
49
+ v-html="blocks[blockId]!.settings.description"
50
+ />
46
51
  </li>
47
52
  </template>
48
53
  </ul>
@@ -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,48 @@
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 || 'num-circle'))
26
+
27
+ const headingClass = computed(() => `h3-${variant.value}`)
28
+
29
+ const iconClass = computed(() => (variant.value === 'tips-badge' ? 'h3-badge' : 'h3-icon'))
30
+
31
+ const { editableAttrs } = 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
+ <h3 :class="headingClass">
43
+ <!-- eslint-disable-next-line vue/no-v-html -->
44
+ <span :class="iconClass" v-bind="editableAttrs('number')" v-html="s.number" />
45
+ <!-- eslint-disable-next-line vue/no-v-html -->
46
+ <span v-bind="editableAttrs('text')" v-html="s.text" />
47
+ </h3>
48
+ </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;
@@ -35,13 +35,14 @@ const { editableAttrs } = useInlineEdit({
35
35
 
36
36
  <template>
37
37
  <h3 :class="{ 'black-h3': variant === 'numbered' }">
38
+ <!-- eslint-disable-next-line vue/no-v-html -->
38
39
  <span
39
40
  v-if="variant === 'numbered' && s.number"
40
41
  class="green-text"
41
42
  v-bind="editableAttrs('number')"
42
- >
43
- {{ s.number }}
44
- </span>
45
- <span v-bind="editableAttrs('title')">{{ s.title }}</span>
43
+ v-html="s.number"
44
+ />
45
+ <!-- eslint-disable-next-line vue/no-v-html -->
46
+ <span v-bind="editableAttrs('title')" v-html="s.title" />
46
47
  </h3>
47
48
  </template>
@@ -5,5 +5,17 @@ type __VLS_Props = {
5
5
  editorMode?: boolean;
6
6
  settings: Record<string, unknown>;
7
7
  };
8
- 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>;
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>;
9
21
  export default _default;
@@ -3,6 +3,8 @@ import type { BlockData } from '@vigilkids/section-core'
3
3
 
4
4
  import { computed } from 'vue'
5
5
 
6
+ import { useInlineEdit } from '../../../composables/useInlineEdit'
7
+
6
8
  const props = defineProps<{
7
9
  blockOrder: string[]
8
10
  blocks: Record<string, BlockData>
@@ -10,6 +12,14 @@ const props = defineProps<{
10
12
  settings: Record<string, unknown>
11
13
  }>()
12
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
+
13
23
  const s = computed(() => props.settings)
14
24
 
15
25
  interface ColumnDef {
@@ -42,9 +52,19 @@ const rows = computed(() =>
42
52
  .filter(id => props.blocks[id]?.type === 'table-row')
43
53
  .map((id) => {
44
54
  const block = props.blocks[id]!
45
- return parseJsonOrArray<string>(block.settings.cells)
55
+ return { id, cells: parseJsonOrArray<string>(block.settings.cells) }
46
56
  }),
47
57
  )
58
+
59
+ // 保留完整 5-emit 契约,与其他 section 统一;columns/cells 为 JSON 聚合字段,内联编辑暂由配置面板承担
60
+ useInlineEdit({
61
+ editorMode: () => !!props.editorMode,
62
+ onSettingUpdate: (key, value) => emit('update:setting', key, value),
63
+ onBlockSettingUpdate: (blockId, key, value) => emit('update:block-setting', blockId, key, value),
64
+ onEditStart: key => emit('inline-edit-start', key),
65
+ onEditEnd: () => emit('inline-edit-end'),
66
+ onUndoRedo: action => emit('undo-redo', action),
67
+ })
48
68
  </script>
49
69
 
50
70
  <template>
@@ -52,19 +72,19 @@ const rows = computed(() =>
52
72
  <table cellspacing="0">
53
73
  <thead align="left">
54
74
  <tr>
75
+ <!-- eslint-disable-next-line vue/no-v-html -->
55
76
  <th
56
77
  v-for="(col, idx) in columns"
57
78
  :key="idx"
58
79
  :style="col.min_width ? { minWidth: `${col.min_width}px` } : undefined"
59
- >
60
- {{ col.label }}
61
- </th>
80
+ v-html="col.label"
81
+ />
62
82
  </tr>
63
83
  </thead>
64
84
  <tbody align="left">
65
- <tr v-for="(row, rowIdx) in rows" :key="rowIdx">
85
+ <tr v-for="row in rows" :key="row.id">
66
86
  <!-- eslint-disable-next-line vue/no-v-html -->
67
- <td v-for="(cell, cellIdx) in row" :key="cellIdx" v-html="cell" />
87
+ <td v-for="(cell, cellIdx) in row.cells" :key="cellIdx" v-html="cell" />
68
88
  </tr>
69
89
  </tbody>
70
90
  </table>
@@ -5,5 +5,17 @@ type __VLS_Props = {
5
5
  editorMode?: boolean;
6
6
  settings: Record<string, unknown>;
7
7
  };
8
- 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>;
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>;
9
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;