@lightspeed/crane 1.1.0 → 1.1.2

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 (51) hide show
  1. package/dist/app.d.mts +198 -11
  2. package/dist/app.d.ts +198 -11
  3. package/dist/app.mjs +1 -1
  4. package/dist/cli.mjs +22 -11
  5. package/package.json +5 -2
  6. package/template/footers/example-footer/ExampleFooter.vue +40 -1
  7. package/template/footers/example-footer/component/LegalLinks.vue +20 -0
  8. package/template/footers/example-footer/component/ReportAbuse.vue +18 -0
  9. package/template/footers/example-footer/entity/color.ts +4 -0
  10. package/template/footers/{settings/translations.ts → example-footer/settings/content.ts} +0 -2
  11. package/template/footers/example-footer/settings/design.ts +11 -0
  12. package/template/footers/example-footer/settings/translations.ts +12 -0
  13. package/template/footers/example-footer/showcases/1.ts +2 -0
  14. package/template/footers/example-footer/showcases/translations.ts +9 -0
  15. package/template/footers/example-footer/type.ts +2 -2
  16. package/template/headers/example-header/ExampleHeader.vue +39 -7
  17. package/template/headers/example-header/assets/account_icon.svg +11 -0
  18. package/template/headers/example-header/assets/cart.svg +20 -0
  19. package/template/headers/example-header/assets/lightspeed_logo.png +0 -0
  20. package/template/headers/example-header/assets/search.svg +13 -0
  21. package/template/headers/example-header/component/Account.vue +20 -0
  22. package/template/headers/example-header/component/Cart.vue +64 -0
  23. package/template/headers/example-header/component/Logo.vue +95 -0
  24. package/template/headers/example-header/component/NavigationMenu.vue +53 -0
  25. package/template/headers/example-header/component/SearchForm.vue +89 -0
  26. package/template/headers/example-header/settings/content.ts +9 -0
  27. package/template/headers/example-header/settings/design.ts +23 -0
  28. package/template/headers/example-header/settings/translations.ts +9 -0
  29. package/template/headers/example-header/showcases/1.ts +40 -0
  30. package/template/headers/example-header/showcases/2.ts +42 -0
  31. package/template/headers/example-header/showcases/translations.ts +17 -0
  32. package/template/headers/example-header/type.ts +2 -2
  33. package/template/package.json +3 -2
  34. package/template/sections/example-section/component/image/ImagesGrid.vue +18 -37
  35. package/template/sections/example-section/settings/content.ts +53 -55
  36. package/template/sections/example-section/settings/translations.ts +27 -24
  37. package/template/sections/example-section/showcases/1.ts +143 -103
  38. package/template/sections/example-section/showcases/2.ts +127 -103
  39. package/template/sections/example-section/showcases/translations.ts +4 -0
  40. package/template/shared/LanguageSelector.vue +75 -0
  41. package/template/templates/template.ts +128 -104
  42. package/types.d.ts +262 -152
  43. package/template/footers/example-footer/component/SampleComponent.vue +0 -11
  44. package/template/footers/settings/content.ts +0 -1
  45. package/template/footers/settings/design.ts +0 -1
  46. package/template/headers/example-header/component/SampleComponent.vue +0 -11
  47. package/template/headers/settings/content.ts +0 -1
  48. package/template/headers/settings/design.ts +0 -1
  49. package/template/headers/settings/layout.ts +0 -1
  50. package/template/headers/settings/translations.ts +0 -5
  51. /package/template/{footers → headers/example-header}/settings/layout.ts +0 -0
@@ -1,17 +1,49 @@
1
1
  <template>
2
- <div
3
- class="custom-header"
4
- >
5
- <div>
6
- the components will sit here
2
+ <div class="custom-header">
3
+ <div class="custom-header__left">
4
+ <Logo />
5
+ <NavigationMenu />
6
+ </div>
7
+ <div class="custom-header__right">
8
+ <SearchForm />
9
+ <LanguageSelector />
10
+ <Account />
11
+ <CartIcon />
7
12
  </div>
8
13
  </div>
9
14
  </template>
10
15
 
11
16
  <script setup lang="ts">
12
-
17
+ import NavigationMenu from './component/NavigationMenu.vue';
18
+ import LanguageSelector from '../../shared/LanguageSelector.vue';
19
+ import CartIcon from './component/Cart.vue';
20
+ import Logo from './component/Logo.vue';
21
+ import SearchForm from './component/SearchForm.vue';
22
+ import Account from './component/Account.vue';
13
23
  </script>
14
24
 
15
25
  <style scoped lang="scss">
16
-
26
+ .custom-header {
27
+ display: flex;
28
+ justify-content: space-between;
29
+ padding: 5px 10px;
30
+ .custom-header__right{
31
+ display: flex;
32
+ flex: 0 0 auto;
33
+ gap: 10px;
34
+ align-items: center;
35
+ justify-content: flex-end;
36
+ order: 3;
37
+ text-align: right;
38
+ }
39
+ }
40
+ .header-content {
41
+ padding: 0 12px;
42
+ height: 48px;
43
+ width: min(1280px, 100%);
44
+ margin: auto;
45
+ display: flex;
46
+ justify-content: space-between;
47
+ align-items: center;
48
+ }
17
49
  </style>
@@ -0,0 +1,11 @@
1
+ <svg
2
+ width="24"
3
+ height="24"
4
+ viewBox="0 0 24 24"
5
+ xmlns="http://www.w3.org/2000/svg"
6
+ >
7
+ <path
8
+ d="M23.5 12.0037C23.5012 10.0898 23.0244 8.20585 22.1129 6.52281C21.2014 4.83976 19.884 3.41084 18.2802 2.36565C16.6764 1.32047 14.8369 0.692104 12.9287 0.537549C11.0204 0.382995 9.10378 0.707143 7.35258 1.48059C5.60138 2.25404 4.07105 3.45232 2.9004 4.96672C1.72975 6.48113 0.955821 8.26374 0.64882 10.1529C0.34182 12.042 0.511461 13.9779 1.14235 15.7848C1.77325 17.5918 2.84543 19.2128 4.26165 20.5006C4.28966 20.5338 4.32226 20.5629 4.35848 20.5869C6.46141 22.4631 9.18149 23.5 12.0001 23.5C14.8188 23.5 17.5388 22.463 19.6417 20.5867C19.6778 20.5628 19.7102 20.5338 19.7381 20.5007C20.9235 19.4252 21.8705 18.1135 22.5184 16.6501C23.1663 15.1867 23.5007 13.604 23.5 12.0037ZM1.42 12.0037C1.41878 10.2648 1.84643 8.55248 2.66509 7.01827C3.48375 5.48405 4.66817 4.17528 6.11348 3.20782C7.55879 2.24035 9.22042 1.64404 10.9512 1.47168C12.6821 1.29931 14.4287 1.55621 16.0365 2.21963C17.6444 2.88305 19.0638 3.93252 20.1691 5.27513C21.2744 6.61775 22.0316 8.21209 22.3735 9.91701C22.7155 11.6219 22.6317 13.3848 22.1295 15.0496C21.6274 16.7145 20.7224 18.2298 19.4947 19.4616C18.3528 17.55 16.5208 16.1493 14.3764 15.5482C15.373 15.0182 16.1638 14.1702 16.6228 13.1392C17.0819 12.1081 17.1828 10.9532 16.9096 9.85816C16.6364 8.76314 16.0047 7.79091 15.1151 7.09614C14.2254 6.40136 13.1289 6.02395 12 6.02395C10.8711 6.02395 9.77458 6.40136 8.88494 7.09614C7.9953 7.79091 7.36363 8.76314 7.09042 9.85816C6.8172 10.9532 6.91814 12.1081 7.37717 13.1392C7.8362 14.1702 8.62696 15.0182 9.62364 15.5482C7.4792 16.1493 5.64721 17.55 4.50533 19.4616C3.52633 18.4819 2.74996 17.3191 2.22057 16.0394C1.69119 14.7598 1.41915 13.3884 1.42 12.0037ZM12 15.2226C11.1812 15.2226 10.3808 14.9799 9.69994 14.5252C9.01912 14.0704 8.48848 13.424 8.17514 12.6678C7.86179 11.9115 7.77981 11.0794 7.93955 10.2765C8.09929 9.4737 8.49359 8.73626 9.07258 8.15745C9.65157 7.57864 10.3892 7.18447 11.1923 7.02478C11.9954 6.86509 12.8278 6.94705 13.5843 7.26029C14.3408 7.57354 14.9874 8.10401 15.4423 8.78461C15.8972 9.46522 16.14 10.2654 16.14 11.084C16.1388 12.1812 15.7022 13.2332 14.9261 14.0091C14.1499 14.785 13.0976 15.2214 12 15.2226ZM5.19947 20.0991C5.88217 18.8976 6.87116 17.8985 8.06574 17.2035C9.26032 16.5084 10.6178 16.1422 12 16.1422C13.3822 16.1422 14.7397 16.5084 15.9343 17.2035C17.1288 17.8985 18.1178 18.8976 18.8005 20.0991C16.897 21.7015 14.4885 22.5803 12 22.5803C9.51148 22.5803 7.10295 21.7015 5.19947 20.0991Z"
9
+ fill="currentColor"
10
+ />
11
+ </svg>
@@ -0,0 +1,20 @@
1
+ <svg
2
+ width="30"
3
+ height="30"
4
+ viewBox="0 0 24 24"
5
+ xmlns="http://www.w3.org/2000/svg"
6
+ >
7
+ <path
8
+ d="M18 23.5H6C3.8 23.5 2 21.7 2 19.5V4.2H22V19.5C22 21.7 20.2 23.5 18 23.5ZM3 5.2V19.5C3 21.2 4.3 22.5 6 22.5H18C19.7 22.5 21 21.2 21 19.5V5.2H3Z"
9
+ />
10
+ <path
11
+ d="M12 1C9.7 1 8 2.5 8 4.5C8 4.8 7.8 5 7.5 5C7.2 5 7 4.8 7 4.5C7 1.8 9.3 0 12 0C14.7 0 17 1.8 17 4.5C17 4.8 16.8 5 16.5 5C16.2 5 16 4.8 16 4.5C16 2.5 14.3 1 12 1Z"
12
+ fill-rule="evenodd"
13
+ clip-rule="evenodd"
14
+ />
15
+ <path
16
+ d="M2 4.18018H22V19.5002C22 21.7093 20.2091 23.5002 18 23.5002H6C3.79086 23.5002 2 21.7093 2 19.5002V4.18018Z"
17
+ fill-rule="evenodd"
18
+ clip-rule="evenodd"
19
+ />
20
+ </svg>
@@ -0,0 +1,13 @@
1
+ <svg
2
+ width="24"
3
+ height="24"
4
+ viewBox="0 0 24 24"
5
+ xmlns="http://www.w3.org/2000/svg"
6
+ >
7
+ <path
8
+ d="M16.8333 9.83333C16.8333 5.96667 13.7 2.86667 9.86667 2.86667C6 2.86667 2.9 6 2.9 9.83333C2.9 13.7 6.03333 16.8 9.86667 16.8C13.7 16.8333 16.8333 13.7 16.8333 9.83333ZM22 21.4L21.4 22L15.0667 15.6667C13.6667 16.9 11.8667 17.6667 9.83333 17.6667C5.5 17.6667 2 14.1667 2 9.83333C2 5.5 5.5 2 9.83333 2C14.1667 2 17.6667 5.5 17.6667 9.83333C17.6667 11.8333 16.9 13.6667 15.6667 15.0667L22 21.4Z"
9
+ fill="#f5faff"
10
+ fill-rule="evenodd"
11
+ clip-rule="evenodd"
12
+ />
13
+ </svg>
@@ -0,0 +1,20 @@
1
+ <template>
2
+ <div v-if="externalContent?.account">
3
+ <a :href="externalContent.account?.url" :target="externalContent.account?.target">
4
+ <img :src="accountIcon" alt="account icon" />
5
+ </a>
6
+ </div>
7
+ </template>
8
+
9
+ <script setup lang="ts">
10
+ import { useVueBaseProps } from '@lightspeed/crane';
11
+ import { computed } from 'vue';
12
+ import { Design } from '../type.ts';
13
+ import accountIcon from '../assets/account_icon.svg';
14
+
15
+ const baseProps = useVueBaseProps<unknown, Design>();
16
+ const externalContent: ExternalContentData = computed(() => baseProps.externalContent).value as ExternalContentData;
17
+ </script>
18
+
19
+ <style lang="scss" scoped>
20
+ </style>
@@ -0,0 +1,64 @@
1
+ <template>
2
+ <div class="cart-icon">
3
+ <a href="/products/cart" role="button">
4
+ <img alt="cart" src="../assets/cart.svg">
5
+ <span
6
+ v-if="cartItemCount > 0"
7
+ class="item-count"
8
+ >
9
+ {{ cartItemCount > 99 ? '99+' : cartItemCount }}
10
+ </span>
11
+ </a>
12
+ </div>
13
+ </template>
14
+
15
+ <script setup>
16
+ import Ecommerce from '@ecwid/sdk';
17
+ import { ref } from 'vue';
18
+
19
+ const cartItemCount = ref(0);
20
+ const ecommerce = new Ecommerce({
21
+ storeId: window.Ecwid.getOwnerId(),
22
+ });
23
+
24
+ function setCartItemCount() {
25
+ ecommerce.cart.get().then((result) => {
26
+ cartItemCount.value = result?.productsQuantity ?? 0;
27
+ });
28
+ }
29
+
30
+ function subscribeOnCartChange() {
31
+ if (typeof document === 'undefined') {
32
+ return;
33
+ }
34
+
35
+ document.addEventListener('visibilitychange', () => {
36
+ if (document.visibilityState !== 'hidden') {
37
+ setCartItemCount();
38
+ }
39
+ }, false);
40
+
41
+ setCartItemCount();
42
+ }
43
+
44
+ subscribeOnCartChange();
45
+ </script>
46
+
47
+ <style scoped>
48
+ .cart-icon {
49
+ position: relative;
50
+ a:visited{
51
+ text-decoration: none;
52
+ color: black;
53
+ }
54
+ }
55
+ .item-count {
56
+ position: absolute;
57
+ top: 50%;
58
+ left: 50%;
59
+ transform: translate(-50%, -50%);
60
+ color: white;
61
+ font-weight: 400;
62
+ font-size: 13px;
63
+ }
64
+ </style>
@@ -0,0 +1,95 @@
1
+ <template>
2
+ <div
3
+ v-if="logoDesign.visible"
4
+ class="logo-section"
5
+ >
6
+ <div
7
+ v-if="logoContent.type === 'TEXT'"
8
+ class="logo-section__text-frame"
9
+ :style="logoFrameStyle"
10
+ >
11
+ <h1
12
+ :style="logoTextStyle"
13
+ >
14
+ {{ logoTextContent }}
15
+ </h1>
16
+ </div>
17
+ <div
18
+ v-if="logoContent.type === 'IMAGE'"
19
+ class="logo-section-image"
20
+ >
21
+ <img
22
+ v-if="logoContent.image?.lowResolutionDesktopImage !== undefined"
23
+ class="logo-section-image__content"
24
+ :src="logoContent.image?.lowResolutionDesktopImage"
25
+ >
26
+ </div>
27
+ </div>
28
+ </template>
29
+
30
+ <script setup lang="ts">
31
+ import { useLogoElementContent, useLogoElementDesign } from '@lightspeed/crane';
32
+ import { computed } from 'vue';
33
+
34
+ function getColor(color: Color | undefined) {
35
+ if (typeof color === 'undefined') {
36
+ return '';
37
+ }
38
+ return color.hex;
39
+ }
40
+
41
+ const logoContent = useLogoElementContent();
42
+ const logoDesign = useLogoElementDesign();
43
+
44
+ const logoTextContent = computed(() => {
45
+ if (logoContent.text !== undefined) {
46
+ if (logoDesign.value.capitalization === 'all') {
47
+ return logoContent.text.toUpperCase();
48
+ }
49
+ if (logoDesign.value.capitalization === 'small') {
50
+ return logoContent.text.toLowerCase();
51
+ }
52
+ }
53
+ return logoContent.text;
54
+ });
55
+
56
+ const logoTextStyle = computed(() => ({
57
+ fontSize: `${logoDesign.value.size}px`,
58
+ fontFamily: logoDesign.value.font,
59
+ color: getColor(logoDesign.value.color),
60
+ 'font-style': logoDesign.value.italic ? 'italic' : 'normal',
61
+ 'font-weight': logoDesign.value.bold ? 'bold' : 'normal',
62
+ 'letter-spacing': `${logoDesign.value.spacing ?? 0}px`,
63
+ }));
64
+
65
+ const logoFrameStyle = computed(() => ({
66
+ 'border-style': logoDesign.value.frame?.visible ? 'solid' : 'hidden',
67
+ 'border-width': `${logoDesign.value.frame?.width ?? 1}px`,
68
+ 'border-color': getColor(logoDesign.value.frame?.color),
69
+ }));
70
+ </script>
71
+
72
+ <style lang="scss" scoped>
73
+ .logo-section {
74
+ height: 100%;
75
+ width: 300px;
76
+ text-align: center;
77
+ }
78
+
79
+ .logo-section__text-frame {
80
+ text-align: center;
81
+ border-radius: 3px;
82
+ }
83
+
84
+ .logo-section-image {
85
+ height: 100%;
86
+ width: 100%;
87
+ display:block;
88
+
89
+ &__content {
90
+ height: 100%;
91
+ width: 100%;
92
+ object-fit: contain;
93
+ }
94
+ }
95
+ </style>
@@ -0,0 +1,53 @@
1
+ <template>
2
+ <nav
3
+ v-if="navigationMenu.hasContent"
4
+ role="navigation"
5
+ >
6
+ <ul>
7
+ <li
8
+ v-for="item in navigationMenu.items"
9
+ :key="item.id"
10
+ >
11
+ <a @click="item.performAction">
12
+ {{ item.title }}
13
+ </a>
14
+ </li>
15
+ </ul>
16
+ </nav>
17
+ </template>
18
+
19
+ <script setup lang="ts">
20
+ import { useNavigationMenuElementContent } from '@lightspeed/crane';
21
+
22
+ const navigationMenu = useNavigationMenuElementContent();
23
+ </script>
24
+
25
+ <style lang="scss" scoped>
26
+ ul {
27
+ gap: 16px;
28
+ display: flex;
29
+ overflow-x: auto;
30
+ white-space: nowrap;
31
+ height: 48px;
32
+ }
33
+
34
+ li {
35
+ list-style: none;
36
+ display: flex;
37
+ align-items: center;
38
+ min-width: fit-content;
39
+ }
40
+
41
+ a {
42
+ cursor: pointer;
43
+ font-size: 16px;
44
+ font-weight: 500;
45
+ color: #080d12;
46
+ text-decoration: none;
47
+ transition: color 0.35s ease;
48
+
49
+ &:hover {
50
+ color: #0056b3
51
+ }
52
+ }
53
+ </style>
@@ -0,0 +1,89 @@
1
+ <template>
2
+ <div class="search-form__wrapper">
3
+ <form
4
+ role="search"
5
+ class="search-form"
6
+ method="get"
7
+ @submit.prevent="openSearchPage"
8
+ >
9
+ <input
10
+ ref="searchInputRef"
11
+ class="search-form__input"
12
+ type="search"
13
+ enterkeyhint="search"
14
+ name="keyword"
15
+ value=""
16
+ autocomplete="off"
17
+ maxlength="2048"
18
+ aria-label="Search"
19
+ placeholder="Search"
20
+ >
21
+ <button
22
+ type="submit"
23
+ aria-label="Search the website"
24
+ class="search-form__button"
25
+ >
26
+ <img src="../assets/search.svg" alt="Search" />
27
+ </button>
28
+ </form>
29
+ </div>
30
+ </template>
31
+
32
+ <script setup lang="ts">
33
+ import { ref } from 'vue';
34
+ import { useInstantsiteJsApi } from '@lightspeed/crane';
35
+
36
+ const instantsiteJsApi = useInstantsiteJsApi();
37
+ const searchInputRef = ref<HTMLInputElement>();
38
+
39
+ function openSearchPage() {
40
+ const searchInput = searchInputRef.value;
41
+ instantsiteJsApi?.openSearchPage(searchInput?.value);
42
+ }
43
+ </script>
44
+
45
+ <style scoped>
46
+ .search-form {
47
+ position: relative;
48
+ }
49
+
50
+ .search-form__wrapper {
51
+ width: 250px;
52
+ margin-right: 10px;
53
+ margin-left: 10px;
54
+ }
55
+
56
+ .search-form__input {
57
+ background-color: #313132;
58
+ color: #f5faff;
59
+ font-size: 16px;
60
+ width: 100%;
61
+ height: 30px;
62
+ padding: 0 40px 0 10px;
63
+ border: 1px solid transparent;
64
+ border-radius: 20px;
65
+ outline: none;
66
+
67
+ &::-webkit-search-cancel-button {
68
+ appearance: none;
69
+ }
70
+ }
71
+
72
+ .search-form__button {
73
+ display: flex;
74
+ position: absolute;
75
+ top: 1px;
76
+ right: 8px;
77
+ align-items: center;
78
+ justify-content: center;
79
+ width: 30px;
80
+ height: 28px;
81
+ border: 0 none;
82
+ cursor: pointer;
83
+
84
+ img {
85
+ width: 20px;
86
+ height: 20px;
87
+ }
88
+ }
89
+ </style>
@@ -0,0 +1,9 @@
1
+ export default {
2
+ menu: {
3
+ type: 'NAVIGATION_MENU',
4
+ },
5
+ logo: {
6
+ type: 'LOGO',
7
+ label: '$label.logo.label',
8
+ },
9
+ } as const;
@@ -0,0 +1,23 @@
1
+ export default {
2
+ logo: {
3
+ type: 'LOGO',
4
+ label: '$label.logo.label',
5
+ colors: ['#FFFFFF66', '#0000004D', '#00000099', '#64C7FF66', '#F9947266', '#C794CD66', '#FFD17466'],
6
+ sizes: [18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60],
7
+ defaults: {
8
+ font: 'global.fontFamily.body',
9
+ size: 20,
10
+ bold: true,
11
+ italic: false,
12
+ color: '#313131',
13
+ visible: true,
14
+ spacing: 2,
15
+ capitalization: 'all',
16
+ frame: {
17
+ visible: true,
18
+ width: 3,
19
+ color: '#313131',
20
+ },
21
+ },
22
+ },
23
+ } as const;
@@ -0,0 +1,9 @@
1
+ export default {
2
+ en: {
3
+ '$label.logo.label': 'Logo',
4
+ },
5
+
6
+ nl: {
7
+ '$label.logo.label': 'Logo',
8
+ },
9
+ } as const;
@@ -0,0 +1,40 @@
1
+ export default {
2
+ showcaseId: '1',
3
+ previewImage: {
4
+ set: {
5
+ ORIGINAL: {
6
+ url: 'example_header_showcase_1_preview.png',
7
+ },
8
+ },
9
+ },
10
+ blockName: '$label.showcase_1.blockName',
11
+ content: {
12
+ logo: {
13
+ type: 'LOGO',
14
+ logoType: 'TEXT',
15
+ text: '$label.showcase_1.logo.text',
16
+ },
17
+ menu: {
18
+ type: 'NAVIGATION_MENU',
19
+ text: '$label.showcase_1.menu.text',
20
+ },
21
+ },
22
+ design: {
23
+ logo: {
24
+ type: 'LOGO',
25
+ font: 'global.fontFamily.body',
26
+ size: 20,
27
+ bold: true,
28
+ italic: true,
29
+ color: '#313131',
30
+ visible: true,
31
+ spacing: 2,
32
+ capitalization: 'none',
33
+ frame: {
34
+ visible: true,
35
+ width: 3,
36
+ color: '#313131',
37
+ },
38
+ },
39
+ },
40
+ } as const;
@@ -0,0 +1,42 @@
1
+ export default {
2
+ showcaseId: '2',
3
+ previewImage: {
4
+ set: {
5
+ ORIGINAL: {
6
+ url: 'custom_section_showcase_2_preview.png',
7
+ },
8
+ },
9
+ },
10
+ blockName: '$label.showcase_2.blockName',
11
+ content: {
12
+ menu: {
13
+ type: 'NAVIGATION_MENU',
14
+ text: '$label.showcase_2.menu.text',
15
+ },
16
+ logo: {
17
+ type: 'LOGO',
18
+ logoType: 'IMAGE',
19
+ imageData: {
20
+ set: {
21
+ LOW_RES: {
22
+ url: 'lightspeed_logo.png',
23
+ },
24
+ MOBILE_WEBP_LOW_RES: {
25
+ url: 'lightspeed_logo.png',
26
+ },
27
+ MOBILE_WEBP_HI_RES: {
28
+ url: 'lightspeed_logo.png',
29
+ },
30
+ WEBP_LOW_RES: {
31
+ url: 'lightspeed_logo.png',
32
+ },
33
+ WEBP_HI_2X_RES: {
34
+ url: 'lightspeed_logo.png',
35
+ },
36
+ },
37
+ borderInfo: {},
38
+ },
39
+ },
40
+ },
41
+ design: {},
42
+ } as const;
@@ -0,0 +1,17 @@
1
+ export default {
2
+ en: {
3
+ '$label.showcase_1.blockName': 'Custom Header',
4
+ '$label.showcase_1.menu.text': 'Navigation Menu',
5
+ '$label.showcase_2.blockName': 'Custom Header',
6
+ '$label.showcase_2.menu.text': 'Navigation Menu',
7
+ '$label.showcase_1.logo.text': 'Example Text Logo',
8
+ },
9
+
10
+ nl: {
11
+ '$label.showcase_1.blockName': 'Custom Header',
12
+ '$label.showcase_1.menu.text': 'Navigatie Menu',
13
+ '$label.showcase_2.blockName': 'Custom Header',
14
+ '$label.showcase_2.menu.text': 'Navigatie Menu',
15
+ '$label.showcase_1.logo.text': 'Voorbeeld Tekst Logo',
16
+ },
17
+ } as const;
@@ -1,5 +1,5 @@
1
- import ContentSettings from '../settings/content.ts';
2
- import DesignSettings from '../settings/design.ts';
1
+ import ContentSettings from './settings/content.ts';
2
+ import DesignSettings from './settings/design.ts';
3
3
 
4
4
  export type Content = InferContentType<typeof ContentSettings>;
5
5
  export type Design = InferDesignType<typeof DesignSettings>;
@@ -7,9 +7,10 @@
7
7
  "deploy": "crane build && crane deploy"
8
8
  },
9
9
  "dependencies": {
10
- "@lightspeed/crane": "1.1.0",
10
+ "@lightspeed/crane": "1.1.2",
11
11
  "@lightspeed/eslint-config-crane": "1.0.2",
12
- "vue": "^3.4.0"
12
+ "vue": "^3.4.0",
13
+ "@ecwid/sdk": "^0.8.0"
13
14
  },
14
15
  "engines": {
15
16
  "node": ">=20"
@@ -1,7 +1,7 @@
1
1
  <template>
2
2
  <div
3
3
  v-if="size > 0"
4
- :class="`image-grid__${images.length}`"
4
+ :class="`image-grid__${images?.length}`"
5
5
  >
6
6
  <div
7
7
  v-for="(image, index) in images"
@@ -19,45 +19,26 @@
19
19
 
20
20
  <script setup lang="ts">
21
21
  import { computed, ref } from 'vue';
22
- import { useImageElementContent, useInputboxElementContent, useTextareaElementContent } from '@lightspeed/crane';
22
+ import {
23
+ useDeckElementContent,
24
+ Card,
25
+ EditorTypes,
26
+ ImageContent,
27
+ TextAreaContent,
28
+ InputBoxContent,
29
+ } from '@lightspeed/crane';
23
30
  import CustomSectionExampleImage from './Image.vue';
24
31
  import { Content } from '../../type.ts';
25
32
 
26
- const imageText1 = useTextareaElementContent<Content>('image_text_1');
27
- const imageText2 = useTextareaElementContent<Content>('image_text_2');
28
- const imageText3 = useTextareaElementContent<Content>('image_text_3');
29
- const imageText4 = useTextareaElementContent<Content>('image_text_4');
30
- const imageContent1 = useImageElementContent<Content>('image_content_1');
31
- const imageContent2 = useImageElementContent<Content>('image_content_2');
32
- const imageContent3 = useImageElementContent<Content>('image_content_3');
33
- const imageContent4 = useImageElementContent<Content>('image_content_4');
34
- const imageLink1 = useInputboxElementContent<Content>('image_link_1');
35
- const imageLink2 = useInputboxElementContent<Content>('image_link_2');
36
- const imageLink3 = useInputboxElementContent<Content>('image_link_3');
37
- const imageLink4 = useInputboxElementContent<Content>('image_link_4');
38
- const images = computed(() => ([
39
- {
40
- text: imageText1,
41
- content: imageContent1,
42
- link: imageLink1,
43
- },
44
- {
45
- text: imageText2,
46
- content: imageContent2,
47
- link: imageLink2,
48
- },
49
- {
50
- text: imageText3,
51
- content: imageContent3,
52
- link: imageLink3,
53
- },
54
- {
55
- text: imageText4,
56
- content: imageContent4,
57
- link: imageLink4,
58
- },
59
- ].filter((image) => image.content.hasContent)));
60
- const size = computed(() => images.value.length);
33
+ const imagesRaw = useDeckElementContent<Content>('images');
34
+ const images = computed(() => (
35
+ imagesRaw?.cards?.map((card: Card) => ({
36
+ text: imagesRaw.getReactiveRef(card, EditorTypes.TEXTAREA, 'image_text') as unknown as TextAreaContent | undefined,
37
+ content: imagesRaw.getReactiveRef(card, EditorTypes.IMAGE, 'image_content') as unknown as ImageContent | undefined,
38
+ link: imagesRaw.getReactiveRef(card, EditorTypes.INPUTBOX, 'image_link') as unknown as InputBoxContent | undefined,
39
+ })).filter((image) => (image.content !== undefined && image.content.hasContent))));
40
+
41
+ const size = computed(() => (images.value?.length ? images.value.length : 0));
61
42
 
62
43
  const windowWidth = ref(window.innerWidth);
63
44
  const onWidthChange = () => { windowWidth.value = window.innerWidth; };