@shopware/cms-base-layer 4.0.0 → 4.1.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 (75) hide show
  1. package/README.md +58 -43
  2. package/app/components/SwCategoryNavigationLink.vue +4 -5
  3. package/app/components/SwMedia3D.vue +8 -3
  4. package/app/components/SwProductAddToCart.vue +27 -4
  5. package/app/components/SwProductCard.vue +26 -4
  6. package/app/components/SwProductCardDetails.vue +9 -2
  7. package/app/components/SwProductListingFilter.vue +1 -1
  8. package/app/components/SwProductListingFilters.vue +10 -222
  9. package/app/components/SwProductListingFiltersHorizontal.vue +15 -202
  10. package/app/components/public/cms/CmsBlockSpatialViewer.vue +7 -7
  11. package/app/components/public/cms/CmsGenericBlock.vue +6 -10
  12. package/app/components/public/cms/CmsGenericElement.md +11 -5
  13. package/app/components/public/cms/CmsGenericElement.vue +17 -11
  14. package/app/components/public/cms/block/CmsBlockAppRenderer.vue +48 -0
  15. package/app/components/public/cms/block/CmsBlockCategoryHeading.vue +19 -0
  16. package/app/components/public/cms/block/CmsBlockCategoryNavigation.vue +3 -2
  17. package/app/components/public/cms/block/CmsBlockCenterText.vue +5 -4
  18. package/app/components/public/cms/block/CmsBlockCrossSelling.vue +3 -2
  19. package/app/components/public/cms/block/CmsBlockCustomForm.vue +3 -2
  20. package/app/components/public/cms/block/CmsBlockForm.vue +3 -2
  21. package/app/components/public/cms/block/CmsBlockGalleryBuybox.vue +4 -3
  22. package/app/components/public/cms/block/CmsBlockImage.vue +3 -2
  23. package/app/components/public/cms/block/CmsBlockImageBubbleRow.vue +5 -4
  24. package/app/components/public/cms/block/CmsBlockImageCover.vue +3 -2
  25. package/app/components/public/cms/block/CmsBlockImageFourColumn.vue +6 -5
  26. package/app/components/public/cms/block/CmsBlockImageGallery.vue +3 -2
  27. package/app/components/public/cms/block/CmsBlockImageGalleryBig.vue +3 -2
  28. package/app/components/public/cms/block/CmsBlockImageHighlightRow.vue +5 -4
  29. package/app/components/public/cms/block/CmsBlockImageSimpleGrid.vue +5 -4
  30. package/app/components/public/cms/block/CmsBlockImageSlider.vue +3 -2
  31. package/app/components/public/cms/block/CmsBlockImageText.vue +4 -3
  32. package/app/components/public/cms/block/CmsBlockImageTextBubble.vue +8 -7
  33. package/app/components/public/cms/block/CmsBlockImageTextCover.vue +4 -3
  34. package/app/components/public/cms/block/CmsBlockImageTextGallery.vue +39 -16
  35. package/app/components/public/cms/block/CmsBlockImageTextRow.vue +8 -7
  36. package/app/components/public/cms/block/CmsBlockImageThreeColumn.vue +5 -4
  37. package/app/components/public/cms/block/CmsBlockImageThreeCover.vue +5 -4
  38. package/app/components/public/cms/block/CmsBlockImageTwoColumn.vue +4 -3
  39. package/app/components/public/cms/block/CmsBlockProductDescriptionReviews.vue +3 -2
  40. package/app/components/public/cms/block/CmsBlockProductHeading.vue +4 -3
  41. package/app/components/public/cms/block/CmsBlockProductListing.vue +3 -2
  42. package/app/components/public/cms/block/CmsBlockProductThreeColumn.vue +5 -4
  43. package/app/components/public/cms/block/CmsBlockSidebarFilter.vue +7 -5
  44. package/app/components/public/cms/block/CmsBlockText.vue +3 -2
  45. package/app/components/public/cms/block/CmsBlockTextHero.vue +3 -2
  46. package/app/components/public/cms/block/CmsBlockTextOnImage.vue +3 -2
  47. package/app/components/public/cms/block/CmsBlockTextThreeColumn.vue +5 -4
  48. package/app/components/public/cms/block/CmsBlockTextTwoColumn.vue +4 -3
  49. package/app/components/public/cms/block/CmsBlockVideo.vue +19 -0
  50. package/app/components/public/cms/block/CmsBlockVimeoVideo.vue +3 -2
  51. package/app/components/public/cms/block/CmsBlockYoutubeVideo.vue +3 -2
  52. package/app/components/public/cms/element/CmsElementCategoryName.md +8 -0
  53. package/app/components/public/cms/element/CmsElementCategoryName.vue +35 -0
  54. package/app/components/public/cms/element/CmsElementProductListing.vue +58 -25
  55. package/app/components/public/cms/element/CmsElementText.vue +11 -10
  56. package/app/components/public/cms/element/CmsElementVideo.md +27 -0
  57. package/app/components/public/cms/element/CmsElementVideo.vue +193 -0
  58. package/app/components/public/cms/section/CmsSectionSidebar.vue +4 -4
  59. package/app/composables/useListingFilters.ts +189 -0
  60. package/app/composables/useSelectedListingFilters.ts +46 -0
  61. package/app/helpers/cms/getAppRendererLayout.test.ts +93 -0
  62. package/app/helpers/cms/getAppRendererLayout.ts +36 -0
  63. package/app/helpers/cms/getCategoryNameContent.test.ts +57 -0
  64. package/app/helpers/cms/getCategoryNameContent.ts +15 -0
  65. package/app/helpers/cms/getTextElementContent.test.ts +79 -0
  66. package/app/helpers/cms/getTextElementContent.ts +37 -0
  67. package/app/helpers/cms/getVideoElementOptions.test.ts +384 -0
  68. package/app/helpers/cms/getVideoElementOptions.ts +142 -0
  69. package/app/helpers/html-to-vue/renderToHtml.test.ts +16 -0
  70. package/app/helpers/html-to-vue/renderer.ts +3 -3
  71. package/app/helpers/product/shouldShowBuyButton.test.ts +21 -0
  72. package/app/helpers/product/shouldShowBuyButton.ts +6 -0
  73. package/app/utils/{useSelectedListingFilters.test.ts → listingFilterState.test.ts} +1 -1
  74. package/app/utils/{useSelectedListingFilters.ts → listingFilterState.ts} +0 -35
  75. package/package.json +10 -10
@@ -1,5 +1,6 @@
1
1
  <script setup lang="ts">
2
2
  import type { CmsBlockImageGallery } from "@shopware/composables";
3
+ import { computed } from "vue";
3
4
 
4
5
  import { useCmsBlock } from "#imports";
5
6
 
@@ -7,9 +8,9 @@ const props = defineProps<{
7
8
  content: CmsBlockImageGallery;
8
9
  }>();
9
10
 
10
- const { getSlotContent } = useCmsBlock(props.content);
11
+ const { getSlotContent } = useCmsBlock(() => props.content);
11
12
 
12
- const cmsContent = getSlotContent("imageGallery");
13
+ const cmsContent = computed(() => getSlotContent("imageGallery"));
13
14
  </script>
14
15
 
15
16
  <template>
@@ -1,5 +1,6 @@
1
1
  <script setup lang="ts">
2
2
  import type { CmsBlockImageGalleryBig } from "@shopware/composables";
3
+ import { computed } from "vue";
3
4
 
4
5
  import { useCmsBlock } from "#imports";
5
6
 
@@ -7,9 +8,9 @@ const props = defineProps<{
7
8
  content: CmsBlockImageGalleryBig;
8
9
  }>();
9
10
 
10
- const { getSlotContent } = useCmsBlock(props.content);
11
+ const { getSlotContent } = useCmsBlock(() => props.content);
11
12
 
12
- const cmsContent = getSlotContent("imageGallery");
13
+ const cmsContent = computed(() => getSlotContent("imageGallery"));
13
14
  </script>
14
15
 
15
16
  <template>
@@ -1,5 +1,6 @@
1
1
  <script setup lang="ts">
2
2
  import type { CmsBlockImageHighlightRow } from "@shopware/composables";
3
+ import { computed } from "vue";
3
4
 
4
5
  import { useCmsBlock } from "#imports";
5
6
 
@@ -7,11 +8,11 @@ const props = defineProps<{
7
8
  content: CmsBlockImageHighlightRow;
8
9
  }>();
9
10
 
10
- const { getSlotContent } = useCmsBlock(props.content);
11
+ const { getSlotContent } = useCmsBlock(() => props.content);
11
12
 
12
- const leftContent = getSlotContent("left");
13
- const rightContent = getSlotContent("right");
14
- const centerContent = getSlotContent("center");
13
+ const leftContent = computed(() => getSlotContent("left"));
14
+ const rightContent = computed(() => getSlotContent("right"));
15
+ const centerContent = computed(() => getSlotContent("center"));
15
16
  </script>
16
17
  <template>
17
18
  <div
@@ -1,5 +1,6 @@
1
1
  <script setup lang="ts">
2
2
  import type { CmsBlockImageSimpleGrid } from "@shopware/composables";
3
+ import { computed } from "vue";
3
4
 
4
5
  import { useCmsBlock } from "#imports";
5
6
 
@@ -7,11 +8,11 @@ const props = defineProps<{
7
8
  content: CmsBlockImageSimpleGrid;
8
9
  }>();
9
10
 
10
- const { getSlotContent } = useCmsBlock(props.content);
11
+ const { getSlotContent } = useCmsBlock(() => props.content);
11
12
 
12
- const leftTopContent = getSlotContent("left-top");
13
- const leftBottomContent = getSlotContent("left-bottom");
14
- const rightContent = getSlotContent("right");
13
+ const leftTopContent = computed(() => getSlotContent("left-top"));
14
+ const leftBottomContent = computed(() => getSlotContent("left-bottom"));
15
+ const rightContent = computed(() => getSlotContent("right"));
15
16
  </script>
16
17
 
17
18
  <template>
@@ -1,5 +1,6 @@
1
1
  <script setup lang="ts">
2
2
  import type { CmsBlockImageSlider } from "@shopware/composables";
3
+ import { computed } from "vue";
3
4
 
4
5
  import { useCmsBlock } from "#imports";
5
6
 
@@ -7,8 +8,8 @@ const props = defineProps<{
7
8
  content: CmsBlockImageSlider;
8
9
  }>();
9
10
 
10
- const { getSlotContent } = useCmsBlock(props.content);
11
- const cmsContent = getSlotContent("imageSlider");
11
+ const { getSlotContent } = useCmsBlock(() => props.content);
12
+ const cmsContent = computed(() => getSlotContent("imageSlider"));
12
13
  </script>
13
14
 
14
15
  <template>
@@ -1,5 +1,6 @@
1
1
  <script setup lang="ts">
2
2
  import type { CmsBlockImageText } from "@shopware/composables";
3
+ import { computed } from "vue";
3
4
 
4
5
  import { useCmsBlock } from "#imports";
5
6
 
@@ -7,10 +8,10 @@ const props = defineProps<{
7
8
  content: CmsBlockImageText;
8
9
  }>();
9
10
 
10
- const { getSlotContent } = useCmsBlock(props.content);
11
+ const { getSlotContent } = useCmsBlock(() => props.content);
11
12
 
12
- const leftContent = getSlotContent("left");
13
- const rightContent = getSlotContent("right");
13
+ const leftContent = computed(() => getSlotContent("left"));
14
+ const rightContent = computed(() => getSlotContent("right"));
14
15
  </script>
15
16
  <template>
16
17
  <div
@@ -1,5 +1,6 @@
1
1
  <script setup lang="ts">
2
2
  import type { CmsBlockImageTextBubble } from "@shopware/composables";
3
+ import { computed } from "vue";
3
4
 
4
5
  import { useCmsBlock } from "#imports";
5
6
 
@@ -7,14 +8,14 @@ const props = defineProps<{
7
8
  content: CmsBlockImageTextBubble;
8
9
  }>();
9
10
 
10
- const { getSlotContent } = useCmsBlock(props.content);
11
+ const { getSlotContent } = useCmsBlock(() => props.content);
11
12
 
12
- const leftText = getSlotContent("left-text");
13
- const leftImage = getSlotContent("left-image");
14
- const centerText = getSlotContent("center-text");
15
- const centerImage = getSlotContent("center-image");
16
- const rightText = getSlotContent("right-text");
17
- const rightImage = getSlotContent("right-image");
13
+ const leftText = computed(() => getSlotContent("left-text"));
14
+ const leftImage = computed(() => getSlotContent("left-image"));
15
+ const centerText = computed(() => getSlotContent("center-text"));
16
+ const centerImage = computed(() => getSlotContent("center-image"));
17
+ const rightText = computed(() => getSlotContent("right-text"));
18
+ const rightImage = computed(() => getSlotContent("right-image"));
18
19
  </script>
19
20
  <template>
20
21
  <div
@@ -1,5 +1,6 @@
1
1
  <script setup lang="ts">
2
2
  import type { CmsBlockImageTextCover } from "@shopware/composables";
3
+ import { computed } from "vue";
3
4
 
4
5
  import { useCmsBlock } from "#imports";
5
6
 
@@ -7,10 +8,10 @@ const props = defineProps<{
7
8
  content: CmsBlockImageTextCover;
8
9
  }>();
9
10
 
10
- const { getSlotContent } = useCmsBlock(props.content);
11
+ const { getSlotContent } = useCmsBlock(() => props.content);
11
12
 
12
- const leftContent = getSlotContent("left");
13
- const rightContent = getSlotContent("right");
13
+ const leftContent = computed(() => getSlotContent("left"));
14
+ const rightContent = computed(() => getSlotContent("right"));
14
15
  </script>
15
16
  <template>
16
17
  <article
@@ -4,6 +4,7 @@ import type {
4
4
  CmsElementImage,
5
5
  CmsElementText,
6
6
  } from "@shopware/composables";
7
+ import { computed } from "vue";
7
8
 
8
9
  import { useCmsBlock } from "#imports";
9
10
 
@@ -11,21 +12,28 @@ const props = defineProps<{
11
12
  content: CmsBlockImageTextGallery;
12
13
  }>();
13
14
 
14
- const { getSlotContent } = useCmsBlock(props.content);
15
+ const { getSlotContent } = useCmsBlock(() => props.content);
15
16
 
16
- const leftTextContent = getSlotContent("left-text") as CmsElementText;
17
- const rightTextContent = getSlotContent("right-text") as CmsElementText;
18
- const centerTextContent = getSlotContent("center-text") as CmsElementText;
17
+ const leftTextContent = computed(
18
+ () => getSlotContent("left-text") as CmsElementText | undefined,
19
+ );
20
+ const rightTextContent = computed(
21
+ () => getSlotContent("right-text") as CmsElementText | undefined,
22
+ );
23
+ const centerTextContent = computed(
24
+ () => getSlotContent("center-text") as CmsElementText | undefined,
25
+ );
19
26
 
20
- const leftImageContent = getSlotContent(
21
- "left-image",
22
- ) as unknown as CmsElementImage;
23
- const rightImageContent = getSlotContent(
24
- "right-image",
25
- ) as unknown as CmsElementImage;
26
- const centerImageContent = getSlotContent(
27
- "center-image",
28
- ) as unknown as CmsElementImage;
27
+ const leftImageContent = computed(
28
+ () => getSlotContent("left-image") as unknown as CmsElementImage | undefined,
29
+ );
30
+ const rightImageContent = computed(
31
+ () => getSlotContent("right-image") as unknown as CmsElementImage | undefined,
32
+ );
33
+ const centerImageContent = computed(
34
+ () =>
35
+ getSlotContent("center-image") as unknown as CmsElementImage | undefined,
36
+ );
29
37
 
30
38
  // TODO: useRouter
31
39
  function onImageClick(
@@ -52,29 +60,44 @@ function onImageClick(
52
60
  >
53
61
  <div class="w-full sm:flex-1">
54
62
  <CmsElementImage
63
+ v-if="leftImageContent"
55
64
  :content="leftImageContent"
56
65
  :style="{ cursor: leftImageContent.data?.url && 'pointer' }"
57
66
  @click="onImageClick(leftImageContent)"
58
67
  />
59
- <CmsElementText :content="leftTextContent" class="self-stretch" />
68
+ <CmsElementText
69
+ v-if="leftTextContent"
70
+ :content="leftTextContent"
71
+ class="self-stretch"
72
+ />
60
73
  </div>
61
74
  <div class="w-full sm:flex-1">
62
75
  <CmsElementImage
76
+ v-if="centerImageContent"
63
77
  :content="centerImageContent"
64
78
  :style="{
65
79
  cursor: centerImageContent.data?.url && 'pointer',
66
80
  }"
67
81
  @click="onImageClick(centerImageContent)"
68
82
  />
69
- <CmsElementText :content="centerTextContent" class="self-stretch" />
83
+ <CmsElementText
84
+ v-if="centerTextContent"
85
+ :content="centerTextContent"
86
+ class="self-stretch"
87
+ />
70
88
  </div>
71
89
  <div class="w-full sm:flex-1">
72
90
  <CmsElementImage
91
+ v-if="rightImageContent"
73
92
  :content="rightImageContent"
74
93
  :style="{ cursor: rightImageContent.data?.url && 'pointer' }"
75
94
  @click="onImageClick(rightImageContent)"
76
95
  />
77
- <CmsElementText :content="rightTextContent" class="self-stretch" />
96
+ <CmsElementText
97
+ v-if="rightTextContent"
98
+ :content="rightTextContent"
99
+ class="self-stretch"
100
+ />
78
101
  </div>
79
102
  </article>
80
103
  </template>
@@ -1,5 +1,6 @@
1
1
  <script setup lang="ts">
2
2
  import type { CmsBlockImageTextRow } from "@shopware/composables";
3
+ import { computed } from "vue";
3
4
 
4
5
  import { useCmsBlock } from "#imports";
5
6
 
@@ -7,14 +8,14 @@ const props = defineProps<{
7
8
  content: CmsBlockImageTextRow;
8
9
  }>();
9
10
 
10
- const { getSlotContent } = useCmsBlock(props.content);
11
+ const { getSlotContent } = useCmsBlock(() => props.content);
11
12
 
12
- const leftImageContent = getSlotContent("left-image");
13
- const leftTextContent = getSlotContent("left-text");
14
- const centerImageContent = getSlotContent("center-image");
15
- const centerTextContent = getSlotContent("center-text");
16
- const rightImageContent = getSlotContent("right-image");
17
- const rightTextContent = getSlotContent("right-text");
13
+ const leftImageContent = computed(() => getSlotContent("left-image"));
14
+ const leftTextContent = computed(() => getSlotContent("left-text"));
15
+ const centerImageContent = computed(() => getSlotContent("center-image"));
16
+ const centerTextContent = computed(() => getSlotContent("center-text"));
17
+ const rightImageContent = computed(() => getSlotContent("right-image"));
18
+ const rightTextContent = computed(() => getSlotContent("right-text"));
18
19
  </script>
19
20
  <template>
20
21
  <div
@@ -1,5 +1,6 @@
1
1
  <script setup lang="ts">
2
2
  import type { CmsBlockImageThreeColumn } from "@shopware/composables";
3
+ import { computed } from "vue";
3
4
 
4
5
  import { useCmsBlock } from "#imports";
5
6
 
@@ -7,11 +8,11 @@ const props = defineProps<{
7
8
  content: CmsBlockImageThreeColumn;
8
9
  }>();
9
10
 
10
- const { getSlotContent } = useCmsBlock(props.content);
11
+ const { getSlotContent } = useCmsBlock(() => props.content);
11
12
 
12
- const leftContent = getSlotContent("left");
13
- const rightContent = getSlotContent("right");
14
- const centerContent = getSlotContent("center");
13
+ const leftContent = computed(() => getSlotContent("left"));
14
+ const rightContent = computed(() => getSlotContent("right"));
15
+ const centerContent = computed(() => getSlotContent("center"));
15
16
  </script>
16
17
  <template>
17
18
  <div class="flex flex-col sm:flex-row justify-start items-start gap-6 w-full">
@@ -1,5 +1,6 @@
1
1
  <script setup lang="ts">
2
2
  import type { CmsBlockImageThreeCover } from "@shopware/composables";
3
+ import { computed } from "vue";
3
4
 
4
5
  import { useCmsBlock } from "#imports";
5
6
 
@@ -7,11 +8,11 @@ const props = defineProps<{
7
8
  content: CmsBlockImageThreeCover;
8
9
  }>();
9
10
 
10
- const { getSlotContent } = useCmsBlock(props.content);
11
+ const { getSlotContent } = useCmsBlock(() => props.content);
11
12
 
12
- const leftContent = getSlotContent("left");
13
- const rightContent = getSlotContent("right");
14
- const centerContent = getSlotContent("center");
13
+ const leftContent = computed(() => getSlotContent("left"));
14
+ const rightContent = computed(() => getSlotContent("right"));
15
+ const centerContent = computed(() => getSlotContent("center"));
15
16
  </script>
16
17
  <template>
17
18
  <div
@@ -1,5 +1,6 @@
1
1
  <script setup lang="ts">
2
2
  import type { CmsBlockImageTwoColumn } from "@shopware/composables";
3
+ import { computed } from "vue";
3
4
 
4
5
  import { useCmsBlock } from "#imports";
5
6
 
@@ -7,10 +8,10 @@ const props = defineProps<{
7
8
  content: CmsBlockImageTwoColumn;
8
9
  }>();
9
10
 
10
- const { getSlotContent } = useCmsBlock(props.content);
11
+ const { getSlotContent } = useCmsBlock(() => props.content);
11
12
 
12
- const leftContent = getSlotContent("left");
13
- const rightContent = getSlotContent("right");
13
+ const leftContent = computed(() => getSlotContent("left"));
14
+ const rightContent = computed(() => getSlotContent("right"));
14
15
  </script>
15
16
  <template>
16
17
  <div
@@ -1,13 +1,14 @@
1
1
  <script setup lang="ts">
2
2
  import type { CmsBlockProductDescriptionReviews } from "@shopware/composables";
3
+ import { computed } from "vue";
3
4
 
4
5
  import { useCmsBlock } from "#imports";
5
6
 
6
7
  const props = defineProps<{
7
8
  content: CmsBlockProductDescriptionReviews;
8
9
  }>();
9
- const { getSlotContent } = useCmsBlock(props.content);
10
- const slotContent = getSlotContent("content");
10
+ const { getSlotContent } = useCmsBlock(() => props.content);
11
+ const slotContent = computed(() => getSlotContent("content"));
11
12
  </script>
12
13
  <template>
13
14
  <div class="cms-block-product-description-reviews">
@@ -1,5 +1,6 @@
1
1
  <script setup lang="ts">
2
2
  import type { CmsBlockProductHeading } from "@shopware/composables";
3
+ import { computed } from "vue";
3
4
 
4
5
  import { useCmsBlock } from "#imports";
5
6
 
@@ -7,10 +8,10 @@ const props = defineProps<{
7
8
  content: CmsBlockProductHeading;
8
9
  }>();
9
10
 
10
- const { getSlotContent } = useCmsBlock(props.content);
11
+ const { getSlotContent } = useCmsBlock(() => props.content);
11
12
 
12
- const leftContent = getSlotContent("left");
13
- const rightContent = getSlotContent("right");
13
+ const leftContent = computed(() => getSlotContent("left"));
14
+ const rightContent = computed(() => getSlotContent("right"));
14
15
  </script>
15
16
 
16
17
  <template>
@@ -1,5 +1,6 @@
1
1
  <script setup lang="ts">
2
2
  import type { CmsBlockProductListing } from "@shopware/composables";
3
+ import { computed } from "vue";
3
4
 
4
5
  import { useCmsBlock } from "#imports";
5
6
 
@@ -7,8 +8,8 @@ const props = defineProps<{
7
8
  content: CmsBlockProductListing;
8
9
  }>();
9
10
 
10
- const { getSlotContent } = useCmsBlock(props.content);
11
- const slotContent = getSlotContent("content");
11
+ const { getSlotContent } = useCmsBlock(() => props.content);
12
+ const slotContent = computed(() => getSlotContent("content"));
12
13
  </script>
13
14
 
14
15
  <template>
@@ -1,5 +1,6 @@
1
1
  <script setup lang="ts">
2
2
  import type { CmsBlockProductThreeColumn } from "@shopware/composables";
3
+ import { computed } from "vue";
3
4
 
4
5
  import { useCmsBlock } from "#imports";
5
6
 
@@ -7,11 +8,11 @@ const props = defineProps<{
7
8
  content: CmsBlockProductThreeColumn;
8
9
  }>();
9
10
 
10
- const { getSlotContent } = useCmsBlock(props.content);
11
+ const { getSlotContent } = useCmsBlock(() => props.content);
11
12
 
12
- const leftContent = getSlotContent("left");
13
- const rightContent = getSlotContent("right");
14
- const centerContent = getSlotContent("center");
13
+ const leftContent = computed(() => getSlotContent("left"));
14
+ const rightContent = computed(() => getSlotContent("right"));
15
+ const centerContent = computed(() => getSlotContent("center"));
15
16
  </script>
16
17
 
17
18
  <template>
@@ -3,6 +3,7 @@ import type {
3
3
  CmsBlockSidebarFilter,
4
4
  CmsElementSidebarFilter,
5
5
  } from "@shopware/composables";
6
+ import { computed } from "vue";
6
7
 
7
8
  import { useCmsBlock } from "#imports";
8
9
 
@@ -10,11 +11,12 @@ const props = defineProps<{
10
11
  content: CmsBlockSidebarFilter;
11
12
  }>();
12
13
 
13
- const { getSlotContent } = useCmsBlock(props.content);
14
- const slotContent = getSlotContent(
15
- "content",
16
- ) as unknown as CmsElementSidebarFilter;
14
+ const { getSlotContent } = useCmsBlock(() => props.content);
15
+ const slotContent = computed(
16
+ () =>
17
+ getSlotContent("content") as unknown as CmsElementSidebarFilter | undefined,
18
+ );
17
19
  </script>
18
20
  <template>
19
- <CmsElementSidebarFilter :content="slotContent" />
21
+ <CmsElementSidebarFilter v-if="slotContent" :content="slotContent" />
20
22
  </template>
@@ -1,5 +1,6 @@
1
1
  <script setup lang="ts">
2
2
  import type { CmsBlockText } from "@shopware/composables";
3
+ import { computed } from "vue";
3
4
 
4
5
  import { useCmsBlock } from "#imports";
5
6
 
@@ -7,9 +8,9 @@ const props = defineProps<{
7
8
  content: CmsBlockText;
8
9
  }>();
9
10
 
10
- const { getSlotContent } = useCmsBlock(props.content);
11
+ const { getSlotContent } = useCmsBlock(() => props.content);
11
12
 
12
- const slotContent = getSlotContent("content");
13
+ const slotContent = computed(() => getSlotContent("content"));
13
14
  </script>
14
15
  <template>
15
16
  <CmsGenericElement :content="slotContent" />
@@ -1,5 +1,6 @@
1
1
  <script setup lang="ts">
2
2
  import type { CmsBlockTextHero } from "@shopware/composables";
3
+ import { computed } from "vue";
3
4
 
4
5
  import { useCmsBlock } from "#imports";
5
6
 
@@ -7,9 +8,9 @@ const props = defineProps<{
7
8
  content: CmsBlockTextHero;
8
9
  }>();
9
10
 
10
- const { getSlotContent } = useCmsBlock(props.content);
11
+ const { getSlotContent } = useCmsBlock(() => props.content);
11
12
 
12
- const slotContent = getSlotContent("content");
13
+ const slotContent = computed(() => getSlotContent("content"));
13
14
  </script>
14
15
  <template>
15
16
  <CmsGenericElement :content="slotContent" />
@@ -1,5 +1,6 @@
1
1
  <script setup lang="ts">
2
2
  import type { CmsBlockTextOnImage } from "@shopware/composables";
3
+ import { computed } from "vue";
3
4
 
4
5
  import { useCmsBlock } from "#imports";
5
6
 
@@ -7,9 +8,9 @@ const props = defineProps<{
7
8
  content: CmsBlockTextOnImage;
8
9
  }>();
9
10
 
10
- const { getSlotContent } = useCmsBlock(props.content);
11
+ const { getSlotContent } = useCmsBlock(() => props.content);
11
12
 
12
- const slotContent = getSlotContent("content");
13
+ const slotContent = computed(() => getSlotContent("content"));
13
14
  </script>
14
15
 
15
16
  <template>
@@ -1,5 +1,6 @@
1
1
  <script setup lang="ts">
2
2
  import type { CmsBlockTextThreeColumn } from "@shopware/composables";
3
+ import { computed } from "vue";
3
4
 
4
5
  import { useCmsBlock } from "#imports";
5
6
 
@@ -7,11 +8,11 @@ const props = defineProps<{
7
8
  content: CmsBlockTextThreeColumn;
8
9
  }>();
9
10
 
10
- const { getSlotContent } = useCmsBlock(props.content);
11
+ const { getSlotContent } = useCmsBlock(() => props.content);
11
12
 
12
- const leftContent = getSlotContent("left");
13
- const rightContent = getSlotContent("right");
14
- const centerContent = getSlotContent("center");
13
+ const leftContent = computed(() => getSlotContent("left"));
14
+ const rightContent = computed(() => getSlotContent("right"));
15
+ const centerContent = computed(() => getSlotContent("center"));
15
16
  </script>
16
17
 
17
18
  <template>
@@ -1,5 +1,6 @@
1
1
  <script setup lang="ts">
2
2
  import type { CmsBlockTextTwoColumn } from "@shopware/composables";
3
+ import { computed } from "vue";
3
4
 
4
5
  import { useCmsBlock } from "#imports";
5
6
 
@@ -7,10 +8,10 @@ const props = defineProps<{
7
8
  content: CmsBlockTextTwoColumn;
8
9
  }>();
9
10
 
10
- const { getSlotContent } = useCmsBlock(props.content);
11
+ const { getSlotContent } = useCmsBlock(() => props.content);
11
12
 
12
- const leftContent = getSlotContent("left");
13
- const rightContent = getSlotContent("right");
13
+ const leftContent = computed(() => getSlotContent("left"));
14
+ const rightContent = computed(() => getSlotContent("right"));
14
15
  </script>
15
16
 
16
17
  <template>
@@ -0,0 +1,19 @@
1
+ <script setup lang="ts">
2
+ import type { CmsBlockVideo } from "@shopware/composables";
3
+ import { computed } from "vue";
4
+
5
+ import { useCmsBlock } from "#imports";
6
+
7
+ const props = defineProps<{
8
+ content: CmsBlockVideo;
9
+ }>();
10
+
11
+ const { getSlotContent } = useCmsBlock(() => props.content);
12
+
13
+ const slotContent = computed(() => getSlotContent("video"));
14
+ </script>
15
+ <template>
16
+ <div class="cms-block-video">
17
+ <CmsGenericElement :content="slotContent" />
18
+ </div>
19
+ </template>
@@ -1,5 +1,6 @@
1
1
  <script setup lang="ts">
2
2
  import type { CmsBlockVimeoVideo } from "@shopware/composables";
3
+ import { computed } from "vue";
3
4
 
4
5
  import { useCmsBlock } from "#imports";
5
6
 
@@ -7,9 +8,9 @@ const props = defineProps<{
7
8
  content: CmsBlockVimeoVideo;
8
9
  }>();
9
10
 
10
- const { getSlotContent } = useCmsBlock(props.content);
11
+ const { getSlotContent } = useCmsBlock(() => props.content);
11
12
 
12
- const slotContent = getSlotContent("video");
13
+ const slotContent = computed(() => getSlotContent("video"));
13
14
  </script>
14
15
  <template>
15
16
  <div class="cms-block-vimeo-video relative">
@@ -1,5 +1,6 @@
1
1
  <script setup lang="ts">
2
2
  import type { CmsBlockYoutubeVideo } from "@shopware/composables";
3
+ import { computed } from "vue";
3
4
 
4
5
  import { useCmsBlock } from "#imports";
5
6
 
@@ -7,9 +8,9 @@ const props = defineProps<{
7
8
  content: CmsBlockYoutubeVideo;
8
9
  }>();
9
10
 
10
- const { getSlotContent } = useCmsBlock(props.content);
11
+ const { getSlotContent } = useCmsBlock(() => props.content);
11
12
 
12
- const slotContent = getSlotContent("video");
13
+ const slotContent = computed(() => getSlotContent("video"));
13
14
  </script>
14
15
  <template>
15
16
  <div class="cms-block-youtube-video relative">
@@ -0,0 +1,8 @@
1
+ Display the category name as the page headline, in the `category-heading` block. Since Shopware 6.7.12 the default listing layouts use it in place of a text element.
2
+
3
+ The element is a text element with its own type:
4
+
5
+ - **Mapped content** (by default `category.name`) is wrapped in `<h1 class="cms-element-category-name-headline">`, as in the Storefront. When the value does not resolve, for example on a page without a category, no empty headline is rendered.
6
+ - **Static content** is authored HTML and is rendered as it is.
7
+
8
+ Rendering goes through `CmsElementText`, so the vertical alignment, link handling and the [`cms-element-text` typography](#cmselementtext) apply. The root carries the `cms-element-category-name` class as well.