cloudcommerce 0.2.3 → 0.3.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 (149) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/ecomplus-stores/monocard/functions/ssr/package.json +0 -2
  3. package/ecomplus-stores/tia-sonia/functions/ssr/package.json +0 -2
  4. package/package.json +6 -6
  5. package/packages/api/package.json +1 -1
  6. package/packages/apps/correios/package.json +2 -2
  7. package/packages/apps/custom-payment/package.json +1 -1
  8. package/packages/apps/custom-shipping/package.json +1 -1
  9. package/packages/apps/datafrete/package.json +2 -2
  10. package/packages/apps/discounts/package.json +1 -1
  11. package/packages/apps/emails/package.json +1 -1
  12. package/packages/apps/fb-conversions/package.json +1 -1
  13. package/packages/apps/frenet/package.json +2 -2
  14. package/packages/apps/galaxpay/package.json +2 -2
  15. package/packages/apps/google-analytics/package.json +2 -2
  16. package/packages/apps/infinitepay/package.json +2 -2
  17. package/packages/apps/jadlog/package.json +2 -2
  18. package/packages/apps/loyalty-points/package.json +1 -1
  19. package/packages/apps/melhor-envio/CHANGELOG.md +1 -0
  20. package/packages/apps/melhor-envio/README.md +1 -0
  21. package/packages/apps/melhor-envio/events.js +1 -0
  22. package/packages/apps/melhor-envio/lib/functions-lib/database.d.ts +18 -0
  23. package/packages/apps/melhor-envio/lib/functions-lib/database.js +115 -0
  24. package/packages/apps/melhor-envio/lib/functions-lib/database.js.map +1 -0
  25. package/packages/apps/melhor-envio/lib/functions-lib/events-to-melhor-envio.d.ts +7 -0
  26. package/packages/apps/melhor-envio/lib/functions-lib/events-to-melhor-envio.js +112 -0
  27. package/packages/apps/melhor-envio/lib/functions-lib/events-to-melhor-envio.js.map +1 -0
  28. package/packages/apps/melhor-envio/lib/functions-lib/new-label.d.ts +42 -0
  29. package/packages/apps/melhor-envio/lib/functions-lib/new-label.js +185 -0
  30. package/packages/apps/melhor-envio/lib/functions-lib/new-label.js.map +1 -0
  31. package/packages/apps/melhor-envio/lib/functions-lib/order-is-valid.d.ts +5 -0
  32. package/packages/apps/melhor-envio/lib/functions-lib/order-is-valid.js +40 -0
  33. package/packages/apps/melhor-envio/lib/functions-lib/order-is-valid.js.map +1 -0
  34. package/packages/apps/melhor-envio/lib/functions-lib/tracking-codes.d.ts +2 -0
  35. package/packages/apps/melhor-envio/lib/functions-lib/tracking-codes.js +164 -0
  36. package/packages/apps/melhor-envio/lib/functions-lib/tracking-codes.js.map +1 -0
  37. package/packages/apps/melhor-envio/lib/index.d.ts +1 -0
  38. package/packages/apps/melhor-envio/lib/index.js +2 -0
  39. package/packages/apps/melhor-envio/lib/index.js.map +1 -0
  40. package/packages/apps/melhor-envio/lib/melhor-envio-events.d.ts +6 -0
  41. package/packages/apps/melhor-envio/lib/melhor-envio-events.js +17 -0
  42. package/packages/apps/melhor-envio/lib/melhor-envio-events.js.map +1 -0
  43. package/packages/apps/melhor-envio/lib/melhor-envio.d.ts +2 -0
  44. package/packages/apps/melhor-envio/lib/melhor-envio.js +6 -0
  45. package/packages/apps/melhor-envio/lib/melhor-envio.js.map +1 -0
  46. package/packages/apps/melhor-envio/lib-mjs/calculate-melhor-envio.mjs +341 -0
  47. package/packages/apps/melhor-envio/lib-mjs/functions/client-melhor-envio.mjs +14 -0
  48. package/packages/apps/melhor-envio/lib-mjs/functions/error-handling.mjs +62 -0
  49. package/packages/apps/melhor-envio/lib-mjs/functions/new-shipment.mjs +119 -0
  50. package/packages/apps/melhor-envio/package.json +36 -0
  51. package/packages/apps/melhor-envio/src/functions-lib/database.ts +140 -0
  52. package/packages/apps/melhor-envio/src/functions-lib/events-to-melhor-envio.ts +137 -0
  53. package/packages/apps/melhor-envio/src/functions-lib/new-label.ts +214 -0
  54. package/packages/apps/melhor-envio/src/functions-lib/order-is-valid.ts +51 -0
  55. package/packages/apps/melhor-envio/src/functions-lib/tracking-codes.ts +191 -0
  56. package/packages/apps/melhor-envio/src/index.ts +1 -0
  57. package/packages/apps/melhor-envio/src/melhor-envio-events.ts +24 -0
  58. package/packages/apps/melhor-envio/src/melhor-envio.ts +7 -0
  59. package/packages/apps/melhor-envio/tsconfig.json +6 -0
  60. package/packages/apps/mercadopago/package.json +2 -2
  61. package/packages/apps/pagarme/package.json +2 -2
  62. package/packages/apps/paghiper/package.json +3 -3
  63. package/packages/apps/pix/package.json +2 -2
  64. package/packages/apps/tiny-erp/package.json +2 -2
  65. package/packages/cli/package.json +1 -1
  66. package/packages/config/package.json +1 -1
  67. package/packages/emails/package.json +3 -3
  68. package/packages/events/lib/firebase.js +2 -0
  69. package/packages/events/lib/firebase.js.map +1 -1
  70. package/packages/events/package.json +2 -1
  71. package/packages/events/src/firebase.ts +2 -0
  72. package/packages/firebase/lib/config.d.ts +4 -0
  73. package/packages/firebase/lib/config.js +7 -0
  74. package/packages/firebase/lib/config.js.map +1 -1
  75. package/packages/firebase/package.json +2 -2
  76. package/packages/firebase/src/config.ts +8 -0
  77. package/packages/i18n/lib/en_us/i19buyTogether.txt +1 -0
  78. package/packages/i18n/lib/en_us/i19buyTogetherWith.txt +1 -0
  79. package/packages/i18n/lib/en_us/i19report.txt +1 -0
  80. package/packages/i18n/lib/en_us/i19toggleMenu.txt +1 -0
  81. package/packages/i18n/lib/en_us/i19uponRequest.txt +1 -0
  82. package/packages/i18n/lib/en_us/i19usedPoints.txt +1 -0
  83. package/packages/i18n/lib/en_us.d.ts +6 -0
  84. package/packages/i18n/lib/en_us.js +6 -0
  85. package/packages/i18n/lib/en_us.js.map +1 -1
  86. package/packages/i18n/lib/pt_br/i19buyTogether.txt +1 -0
  87. package/packages/i18n/lib/pt_br/i19buyTogetherWith.txt +1 -0
  88. package/packages/i18n/lib/pt_br/i19report.txt +1 -0
  89. package/packages/i18n/lib/pt_br/i19toggleMenu.txt +1 -0
  90. package/packages/i18n/lib/pt_br/i19uponRequest.txt +1 -0
  91. package/packages/i18n/lib/pt_br/i19usedPoints.txt +1 -0
  92. package/packages/i18n/lib/pt_br.d.ts +6 -0
  93. package/packages/i18n/lib/pt_br.js +6 -0
  94. package/packages/i18n/lib/pt_br.js.map +1 -1
  95. package/packages/i18n/package.json +1 -1
  96. package/packages/i18n/src/en_us.ts +6 -0
  97. package/packages/i18n/src/pt_br.ts +6 -0
  98. package/packages/modules/lib/firebase/call-app-module.js +5 -0
  99. package/packages/modules/lib/firebase/call-app-module.js.map +1 -1
  100. package/packages/modules/package.json +3 -2
  101. package/packages/modules/src/firebase/call-app-module.ts +5 -0
  102. package/packages/passport/package.json +1 -1
  103. package/packages/ssr/package.json +3 -4
  104. package/packages/storefront/.eslintrc.cjs +1 -1
  105. package/packages/storefront/astro.config.mjs +8 -1
  106. package/packages/storefront/dist/client/_astro/PitchBar.209c6645.js +1 -0
  107. package/packages/storefront/dist/client/_astro/Prices.6fbcb5ac.js +1 -0
  108. package/packages/storefront/dist/client/_astro/Prices.vue_vue_type_script_setup_true_lang.44f23680.js +1 -0
  109. package/packages/storefront/dist/client/_astro/ProductCard.ee5eee91.js +1 -0
  110. package/packages/storefront/dist/client/_astro/ShopHeader.b801c785.js +1 -0
  111. package/packages/storefront/dist/client/_astro/_...slug_.32968ccf.css +1 -0
  112. package/packages/storefront/dist/client/_astro/client.5a46cc02.js +1 -0
  113. package/packages/storefront/dist/client/_astro/index.844a4059.js +1 -0
  114. package/packages/storefront/dist/client/_astro/{modules-info.dde776b4.js → modules-info.d9373e21.js} +1 -1
  115. package/packages/storefront/dist/client/_astro/runtime-core.esm-bundler.f04cee62.js +1 -0
  116. package/packages/storefront/dist/client/_astro/runtime-dom.esm-bundler.00313542.js +1 -0
  117. package/packages/storefront/dist/client/_astro/server.60de185d.css +1 -0
  118. package/packages/storefront/dist/client/_astro/use-component-variant.58788b6e.js +1 -0
  119. package/packages/storefront/dist/client/fallback/index.html +13 -7
  120. package/packages/storefront/dist/client/sw.js +1 -1
  121. package/packages/storefront/dist/server/chunks/pages/{all.c27193d6.mjs → all.23de4e5c.mjs} +444 -186
  122. package/packages/storefront/dist/server/chunks/{prerender.89f63027.mjs → prerender.f40361a3.mjs} +0 -0
  123. package/packages/storefront/dist/server/entry.mjs +39 -4452
  124. package/packages/storefront/package.json +4 -5
  125. package/packages/storefront/src/lib/assets/base.css +16 -11
  126. package/packages/storefront/src/lib/components/Carousel.vue +52 -82
  127. package/packages/storefront/src/lib/components/Drawer.vue +103 -0
  128. package/packages/storefront/src/lib/components/PitchBar.vue +16 -11
  129. package/packages/storefront/src/lib/components/Prices.vue +5 -5
  130. package/packages/storefront/src/lib/components/ShopHeader.vue +82 -0
  131. package/packages/storefront/src/lib/components/StickyHeader.vue +71 -43
  132. package/packages/storefront/src/lib/components/globals/Fade.vue +10 -14
  133. package/packages/storefront/src/lib/composables/use-component-variant.ts +6 -2
  134. package/packages/storefront/src/lib/composables/use-prices.ts +4 -2
  135. package/packages/storefront/src/lib/layouts/BaseBody.astro +1 -0
  136. package/packages/storefront/src/lib/layouts/PagesHeader.astro +28 -13
  137. package/packages/storefront/tailwind.config.cjs +4 -0
  138. package/packages/storefront/uno.config.cjs +1 -1
  139. package/packages/types/package.json +1 -1
  140. package/packages/storefront/dist/client/_astro/PitchBar.f3579a5b.js +0 -1
  141. package/packages/storefront/dist/client/_astro/Prices.8e5cead5.js +0 -1
  142. package/packages/storefront/dist/client/_astro/Prices.vue_vue_type_script_setup_true_lang.b8cbeb54.js +0 -1
  143. package/packages/storefront/dist/client/_astro/ProductCard.6d8b6d86.js +0 -1
  144. package/packages/storefront/dist/client/_astro/StickyHeader.7b0f3963.js +0 -1
  145. package/packages/storefront/dist/client/_astro/_...slug_.97285eba.css +0 -1
  146. package/packages/storefront/dist/client/_astro/client.3e777d4c.js +0 -1
  147. package/packages/storefront/dist/client/_astro/runtime-core.esm-bundler.7cf33881.js +0 -1
  148. package/packages/storefront/dist/client/_astro/runtime-dom.esm-bundler.1a4c7407.js +0 -1
  149. package/packages/storefront/dist/client/_astro/server.4d9646d8.css +0 -1
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cloudcommerce/storefront",
3
3
  "type": "module",
4
- "version": "0.2.3",
4
+ "version": "0.3.0",
5
5
  "description": "E-Com Plus Cloud Commerce storefront with Astro",
6
6
  "main": "src/index.js",
7
7
  "repository": {
@@ -35,22 +35,21 @@
35
35
  "@cloudcommerce/i18n": "workspace:*",
36
36
  "@ecomplus/utils": "1.5.0-rc.3",
37
37
  "@fastify/deepmerge": "^1.3.0",
38
- "@headlessui/vue": "^1.7.7",
38
+ "@headlessui/vue": "^1.7.8",
39
39
  "@iconify-json/fa6-brands": "^1.1.8",
40
40
  "@iconify-json/heroicons": "^1.1.8",
41
41
  "@iconify-json/logos": "^1.1.22",
42
42
  "@vite-pwa/astro": "^0.0.1",
43
- "@vueuse/core": "^9.11.1",
43
+ "@vueuse/core": "^9.12.0",
44
44
  "astro": "^2.0.2",
45
45
  "chroma-js": "^2.4.2",
46
46
  "dotenv": "^16.0.3",
47
47
  "firebase": "^9.16.0",
48
48
  "image-size": "^1.0.2",
49
- "lodash": "^4.17.21",
50
49
  "semver": "^7.3.8",
51
50
  "sharp": "^0.31.3",
52
51
  "tailwindcss": "^3.2.4",
53
- "unocss": "^0.48.4",
52
+ "unocss": "^0.49.1",
54
53
  "vite": "^4.0.4",
55
54
  "vite-plugin-pwa": "^0.14.1",
56
55
  "vue": "^3.2.45"
@@ -1,5 +1,4 @@
1
1
  :root {
2
- --content-max-width: 80rem;
3
2
  --font-size: 14.5px;
4
3
  --font-sans: var(--custom-font-sans, ui-sans-serif),
5
4
  system-ui, -apple-system, BlinkMacSystemFont,
@@ -8,6 +7,7 @@
8
7
  --font-mono: var(--custom-font-mono, ui-monospace),
9
8
  SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
10
9
  --font-family: var(--font-sans);
10
+ --transition-fast: 75ms linear;
11
11
  --transition: .15s ease-in-out;
12
12
  --transition-slow: .25s ease-in-out;
13
13
  --transition-slower: .45s ease-in-out;
@@ -28,6 +28,7 @@
28
28
 
29
29
  @media (prefers-reduced-motion: reduce) {
30
30
  :root {
31
+ --transition-fast: 0s;
31
32
  --transition: 0s;
32
33
  --transition-slow: 0s;
33
34
  --transition-slower: .15s linear;
@@ -63,16 +64,6 @@ html {
63
64
  }
64
65
  }
65
66
 
66
- body > header,
67
- body > main,
68
- body > footer {
69
- margin-left: auto;
70
- margin-right: auto;
71
- }
72
- body > main {
73
- max-width: var(--content-max-width);
74
- }
75
-
76
67
  :focus-visible {
77
68
  outline-color: var(--c-outline, rgba(var(--rgb-secondary), .1));
78
69
  }
@@ -95,3 +86,17 @@ body {
95
86
  background: var(--c-background);
96
87
  color: var(--c-on-background);
97
88
  }
89
+
90
+ /*
91
+ Custom elements for responsive tricks in /content JSON.
92
+ Avoids the need of escape \" for class names with common elements.
93
+ */
94
+
95
+ d-md {
96
+ display: none;
97
+ }
98
+ @screen md {
99
+ d-md {
100
+ display: inline;
101
+ }
102
+ }
@@ -4,13 +4,13 @@ import {
4
4
  onMounted,
5
5
  onBeforeUnmount,
6
6
  ref,
7
+ computed,
7
8
  watch,
8
9
  toRef,
9
10
  nextTick,
10
11
  provide,
11
12
  } from 'vue';
12
- import debounce from 'lodash/debounce';
13
- import { useElementHover } from '@vueuse/core';
13
+ import { useDebounceFn, useElementHover, useScroll } from '@vueuse/core';
14
14
  import { carouselKey } from './_injection-keys';
15
15
  import CarouselControl from './CarouselControl.vue';
16
16
 
@@ -20,58 +20,30 @@ export interface Props {
20
20
  autoplay?: number; // milliseconds
21
21
  }
22
22
 
23
- const approximatelyEqual = (v1, v2, epsilon) => {
24
- return Math.abs(v1 - v2) <= epsilon;
25
- };
26
- const SCROLL_DEBOUNCE = 100;
27
- const RESIZE_DEBOUNCE = 410;
28
-
29
23
  const props = withDefaults(defineProps<Props>(), {
30
24
  as: 'ul',
31
25
  modelValue: 1,
32
26
  });
33
27
  const emit = defineEmits([
34
28
  'update:modelValue',
35
- 'bound-left',
36
- 'bound-right',
37
29
  ]);
38
-
39
- const currentPage = ref(props.modelValue - 1);
30
+ const currentIndex = ref(props.modelValue - 1);
40
31
  watch(toRef(props, 'modelValue'), (modelValue) => {
41
- currentPage.value = modelValue - 1;
32
+ currentIndex.value = modelValue - 1;
42
33
  });
43
- watch(currentPage, (current, previous) => {
34
+ watch(currentIndex, (current, previous) => {
44
35
  if (current !== previous) {
45
36
  emit('update:modelValue', current + 1);
46
37
  }
47
38
  });
48
39
  const wrapper = ref<HTMLElement>(null);
49
- const isBoundLeft = ref(true);
50
- const isBoundRight = ref(false);
40
+ const { x: currentPos, isScrolling, arrivedState } = useScroll(wrapper);
41
+ const isBoundLeft = computed(() => arrivedState.left);
42
+ const isBoundRight = computed(() => arrivedState.right);
51
43
  const slidesWidth = ref([]);
52
44
  const wrapperScrollWidth = ref(0);
53
45
  const wrapperVisibleWidth = ref(0);
54
- const currentPos = ref(0);
55
- const maxPages = ref(0);
56
- const onResizeFn = ref(null);
57
- const onScrollFn = ref(null);
58
- const calcBounds = () => {
59
- // Find the closest point, with 5px approximate.
60
- const _isBoundLeft = approximatelyEqual(currentPos.value, 0, 5);
61
- const _isBoundRight = approximatelyEqual(
62
- wrapperScrollWidth.value - wrapperVisibleWidth.value,
63
- currentPos.value,
64
- 5,
65
- );
66
- if (_isBoundLeft) {
67
- emit('bound-left', true);
68
- }
69
- isBoundLeft.value = _isBoundLeft;
70
- if (_isBoundRight) {
71
- emit('bound-right', true);
72
- }
73
- isBoundRight.value = _isBoundRight;
74
- };
46
+ const indexCount = ref(0);
75
47
  const calcWrapperWidth = () => {
76
48
  wrapperScrollWidth.value = wrapper.value.scrollWidth;
77
49
  wrapperVisibleWidth.value = wrapper.value.offsetWidth;
@@ -84,48 +56,27 @@ const calcSlidesWidth = () => {
84
56
  }));
85
57
  };
86
58
  const calcNextWidth = (direction) => {
87
- const nextSlideIndex = direction > 0 ? currentPage.value : currentPage.value + direction;
88
- const width = slidesWidth.value[nextSlideIndex].width || 0;
59
+ const nextSlideIndex = direction > 0
60
+ ? currentIndex.value : currentIndex.value + direction;
61
+ const width = slidesWidth.value[nextSlideIndex]?.width || 0;
89
62
  if (!width) {
90
63
  return 0;
91
64
  }
92
65
  return width * direction;
93
66
  };
94
- const calcCurrentPage = () => {
95
- const getCurrentPage = slidesWidth.value.findIndex((slide) => {
67
+ const calcCurrentIndex = () => {
68
+ const getCurrentIndex = slidesWidth.value.findIndex((slide: HTMLElement) => {
96
69
  // Find the closest point, with 5px approximate.
97
- return approximatelyEqual(slide.offsetLeft, currentPos.value, 5);
70
+ return Math.abs(slide.offsetLeft - currentPos.value) <= 5;
98
71
  });
99
- if (getCurrentPage !== -1 && getCurrentPage !== -2) {
100
- currentPage.value = getCurrentPage || 0;
72
+ if (getCurrentIndex > -1) {
73
+ currentIndex.value = getCurrentIndex || 0;
101
74
  }
102
75
  };
103
- const calcCurrentPosition = () => {
104
- currentPos.value = wrapper.value.scrollLeft || 0;
105
- };
106
- const calcMaxPages = () => {
76
+ const calcIndexCount = () => {
107
77
  const maxPos = wrapperScrollWidth.value - wrapperVisibleWidth.value;
108
- maxPages.value = slidesWidth.value
109
- .findIndex(({ offsetLeft }) => (offsetLeft >= maxPos));
110
- };
111
- const calcOnInit = () => {
112
- if (!wrapper.value) {
113
- return;
114
- }
115
- calcWrapperWidth();
116
- calcSlidesWidth();
117
- calcCurrentPosition();
118
- calcCurrentPage();
119
- calcBounds();
120
- calcMaxPages();
121
- };
122
- const calcOnScroll = () => {
123
- if (!wrapper.value) {
124
- return;
125
- }
126
- calcCurrentPosition();
127
- calcCurrentPage();
128
- calcBounds();
78
+ indexCount.value = slidesWidth.value
79
+ .findIndex(({ offsetLeft }) => (offsetLeft >= maxPos - 5));
129
80
  };
130
81
  let autoplayTimer = null;
131
82
  const restartAutoplay = () => {
@@ -140,13 +91,13 @@ const restartAutoplay = () => {
140
91
  const changeSlide = (direction: number) => {
141
92
  if (direction < 0) {
142
93
  if (isBoundLeft.value) {
143
- calcMaxPages();
144
- currentPage.value = maxPages.value - 1;
94
+ calcIndexCount();
95
+ currentIndex.value = indexCount.value - 1;
145
96
  changeSlide(1);
146
97
  return;
147
98
  }
148
99
  } else if (isBoundRight.value) {
149
- currentPage.value = 1;
100
+ currentIndex.value = 1;
150
101
  changeSlide(-1);
151
102
  return;
152
103
  }
@@ -156,37 +107,50 @@ const changeSlide = (direction: number) => {
156
107
  restartAutoplay();
157
108
  }
158
109
  };
110
+ watch(isScrolling, (_isScrolling: boolean) => {
111
+ if (_isScrolling) {
112
+ clearTimeout(autoplayTimer);
113
+ } else {
114
+ calcCurrentIndex();
115
+ restartAutoplay();
116
+ }
117
+ });
159
118
  const carousel = ref(null);
160
119
  const isHovered = useElementHover(carousel);
161
- watch(isHovered, (_isHovered) => {
120
+ watch(isHovered, (_isHovered: boolean) => {
162
121
  if (_isHovered) {
163
122
  clearTimeout(autoplayTimer);
164
123
  } else {
165
124
  restartAutoplay();
166
125
  }
167
126
  });
127
+ const calcOnInit = () => {
128
+ if (!wrapper.value) {
129
+ return;
130
+ }
131
+ calcWrapperWidth();
132
+ calcSlidesWidth();
133
+ calcCurrentIndex();
134
+ calcIndexCount();
135
+ };
136
+ const onResize = useDebounceFn(calcOnInit, 400);
168
137
  onMounted(() => {
169
138
  calcOnInit();
170
139
  if (!import.meta.env.SSR) {
171
- // Assign to new variable and keep reference for removeEventListener (Avoid Memory Leaks)
172
- onScrollFn.value = debounce(calcOnScroll, SCROLL_DEBOUNCE);
173
- onResizeFn.value = debounce(calcOnInit, RESIZE_DEBOUNCE);
174
- wrapper.value.addEventListener('scroll', onScrollFn.value);
175
- window.addEventListener('resize', onResizeFn.value);
176
140
  nextTick(() => {
177
141
  [...wrapper.value.children].forEach((slide: HTMLElement) => {
178
142
  slide.setAttribute('tabindex', '0');
179
143
  });
180
144
  });
181
145
  restartAutoplay();
146
+ window.addEventListener('resize', onResize);
182
147
  }
183
148
  });
184
149
  onBeforeUnmount(() => {
185
150
  if (!import.meta.env.SSR) {
186
- wrapper.value.removeEventListener('scroll', onScrollFn.value);
187
- window.removeEventListener('resize', onResizeFn.value);
188
- clearTimeout(autoplayTimer);
151
+ window.removeEventListener('resize', onResize);
189
152
  }
153
+ clearTimeout(autoplayTimer);
190
154
  });
191
155
  provide(carouselKey, {
192
156
  autoplay: toRef(props, 'autoplay'),
@@ -204,7 +168,13 @@ provide(carouselKey, {
204
168
  <!-- @slot Slot for Arrows -->
205
169
  <slot
206
170
  name="controls"
207
- v-bind="{ changeSlide, isBoundLeft, isBoundRight }"
171
+ v-bind="{
172
+ changeSlide,
173
+ isBoundLeft,
174
+ isBoundRight,
175
+ currentPage: currentIndex + 1,
176
+ pageCount: indexCount + 1,
177
+ }"
208
178
  >
209
179
  <CarouselControl :direction="-1">
210
180
  <slot name="previous" />
@@ -0,0 +1,103 @@
1
+ <script setup lang="ts">
2
+ import {
3
+ toRef,
4
+ ref,
5
+ computed,
6
+ watch,
7
+ } from 'vue';
8
+ import useComponentVariant from '@@sf/composables/use-component-variant';
9
+
10
+ export interface Props {
11
+ modelValue?: boolean;
12
+ placement?: 'start' | 'end' | 'top' | 'bottom';
13
+ isTeleported?: boolean;
14
+ hasCloseButton?: boolean;
15
+ }
16
+
17
+ const props = withDefaults(defineProps<Props>(), {
18
+ modelValue: false,
19
+ placement: 'start',
20
+ isTeleported: false,
21
+ hasCloseButton: true,
22
+ });
23
+ const emit = defineEmits([
24
+ 'update:modelValue',
25
+ ]);
26
+ const close = () => emit('update:modelValue', false);
27
+ const anchor = ref(null);
28
+ const canvas = ref(null);
29
+ const outsideClickListener = (ev: MouseEvent) => {
30
+ if (!canvas.value?.contains(ev.target)) {
31
+ close();
32
+ }
33
+ };
34
+ const escClickListener = (ev: KeyboardEvent) => {
35
+ if (ev.key === 'Escape') {
36
+ close();
37
+ }
38
+ };
39
+ watch(toRef(props, 'modelValue'), async (isOpen) => {
40
+ const header = anchor.value.closest('[class*="backdrop-"]');
41
+ if (isOpen) {
42
+ document.body.style.overflow = 'hidden';
43
+ if (header) {
44
+ header.style.backdropFilter = 'none';
45
+ }
46
+ setTimeout(() => {
47
+ document.addEventListener('click', outsideClickListener, { passive: true });
48
+ document.addEventListener('keydown', escClickListener, { passive: true });
49
+ }, 500);
50
+ } else {
51
+ document.body.style.overflow = null;
52
+ if (header) {
53
+ setTimeout(() => {
54
+ header.style.backdropFilter = null;
55
+ }, 500);
56
+ }
57
+ document.removeEventListener('click', outsideClickListener);
58
+ document.removeEventListener('keydown', escClickListener);
59
+ }
60
+ });
61
+ const slideTo = computed(() => {
62
+ switch (props.placement) {
63
+ case 'start': return 'left';
64
+ case 'end': return 'right';
65
+ case 'top': return 'up';
66
+ default: return 'down';
67
+ }
68
+ });
69
+ const componentVariant = useComponentVariant(props, ['placement']);
70
+ </script>
71
+
72
+ <template>
73
+ <div ref="anchor" class="relative">
74
+ <Teleport to="#teleported" :disabled="!isTeleported">
75
+ <Fade :slide="slideTo" speed="slow" is-floating>
76
+ <dialog
77
+ v-if="modelValue"
78
+ class="w-screen max-w-sm p-0 z-50"
79
+ :class="isTeleported ? 'fixed top-0 left-0' : 'absolute'"
80
+ :open="modelValue"
81
+ :data-drawer="componentVariant"
82
+ >
83
+ <div ref="canvas" class="relative">
84
+ <button
85
+ v-if="hasCloseButton"
86
+ type="button"
87
+ :aria-label="$t.i19close"
88
+ @click.prevent="close"
89
+ class="absolute top-2"
90
+ :class="placement === 'end' ? 'left-2' : 'right-2'"
91
+ data-drawer-close
92
+ >
93
+ <slot name="close">
94
+ <i class="i-close text-base-400 text-3xl"></i>
95
+ </slot>
96
+ </button>
97
+ <slot />
98
+ </div>
99
+ </dialog>
100
+ </Fade>
101
+ </Teleport>
102
+ </div>
103
+ </template>
@@ -24,7 +24,7 @@ const countValidSlides = computed(() => {
24
24
  </script>
25
25
 
26
26
  <template>
27
- <div data-pitch-bar class="bg-base-100">
27
+ <div class="bg-base-100" data-pitch-bar>
28
28
  <div class="container md:w-2/3 mx-auto px-3 py-1">
29
29
  <Carousel :autoplay="countValidSlides > 1 ? 7000 : null">
30
30
  <li v-for="(slide, i) in slides" :key="i">
@@ -32,6 +32,7 @@ const countValidSlides = computed(() => {
32
32
  :is="slide.href ? 'ALink' : 'span'"
33
33
  :href="slide.href"
34
34
  :target="slide.target"
35
+ class="inline-block px-8"
35
36
  :class="slide.href ? 'hover:underline' : null"
36
37
  >
37
38
  <slot name="slide" v-bind="{ slide, i, parsedContents }">
@@ -39,21 +40,25 @@ const countValidSlides = computed(() => {
39
40
  v-if="parsedContents[i]"
40
41
  v-html="parsedContents[i]"
41
42
  class="prose text-sm text-base-800"
43
+ data-pitch-bar-slide
42
44
  ></span>
43
45
  </slot>
44
46
  </component>
45
47
  </li>
46
48
  <template #controls>
47
- <div
48
- v-show="countValidSlides > 1"
49
- class="text-xl leading-none text-base-400"
50
- >
51
- <CarouselControl
52
- :direction="-1"
53
- class="pr-2 bg-base-100 hover:text-base-700"
54
- />
55
- <CarouselControl class="pl-2 bg-base-100 hover:text-base-700" />
56
- </div>
49
+ <slot name="controls" v-bind="{ countValidSlides }">
50
+ <div
51
+ v-show="countValidSlides > 1"
52
+ class="text-xl leading-none text-base-400"
53
+ data-pitch-bar-controls
54
+ >
55
+ <CarouselControl
56
+ :direction="-1"
57
+ class="pr-2 bg-base-100 hover:text-base-700"
58
+ />
59
+ <CarouselControl class="pl-2 bg-base-100 hover:text-base-700" />
60
+ </div>
61
+ </slot>
57
62
  </template>
58
63
  </Carousel>
59
64
  </div>
@@ -7,7 +7,7 @@ export interface Props {
7
7
  product?: Partial<Products> & { price: number, final_price?: number };
8
8
  price?: number;
9
9
  basePrice?: number;
10
- isAmountTotal?: boolean,
10
+ isAmountTotal?: boolean;
11
11
  installmentsOption?: ListPaymentsResponse['installments_option'];
12
12
  discountOption?: ListPaymentsResponse['discount_option'];
13
13
  isBig?: boolean;
@@ -37,9 +37,9 @@ const componentVariant = useComponentVariant(props);
37
37
  </script>
38
38
 
39
39
  <template>
40
- <div :data-prices="componentVariant" class="text-base-600">
40
+ <div class="text-base-600" :data-prices="componentVariant">
41
41
  <slot v-if="comparePrice" name="compare" v-bind="{ salePrice, comparePrice }">
42
- <span data-prices-compare class="text-base-500 mr-1">
42
+ <span class="text-base-500 mr-1" data-prices-compare>
43
43
  <slot name="compare-pre">
44
44
  <small v-if="isLiteral">
45
45
  {{ `${$t.i19from} ` }}
@@ -56,7 +56,7 @@ const componentVariant = useComponentVariant(props);
56
56
  </span>
57
57
  </slot>
58
58
  <slot name="sale" v-bind="{ salePrice }">
59
- <strong data-prices-sale class="inline-block text-base-800">
59
+ <strong class="inline-block text-base-800" data-prices-sale>
60
60
  <slot name="sale-pre">
61
61
  <small v-if="hasVariedPrices">
62
62
  {{ `${$t.i19asOf} ` }}
@@ -74,7 +74,7 @@ const componentVariant = useComponentVariant(props);
74
74
  name="cashback"
75
75
  v-bind="{ salePrice, cashbackValue, cashbackPercentage }"
76
76
  >
77
- <div v-if="hasCashback" data-prices-cashback class="relative z-10">
77
+ <div v-if="hasCashback" class="relative z-10" data-prices-cashback>
78
78
  <span :data-tooltip="$t.i19get$1back
79
79
  .replace('$1', $percentage(cashbackPercentage))">
80
80
  <slot name="cashback-pre">
@@ -0,0 +1,82 @@
1
+ <script setup lang="ts">
2
+ import { ref } from 'vue';
3
+ import { i19myAccount, i19openCart, i19searchProducts } from '@@i18n';
4
+ import Drawer from '@@sf/components/Drawer.vue';
5
+ import StickyHeader from '@@sf/components/StickyHeader.vue';
6
+
7
+ const buttons = ref({
8
+ search: {
9
+ icon: 'i-search',
10
+ onClick: () => {},
11
+ label: i19searchProducts,
12
+ },
13
+ account: {
14
+ icon: 'i-account',
15
+ onClick: () => {},
16
+ label: i19myAccount,
17
+ },
18
+ cart: {
19
+ icon: 'i-shopping-cart',
20
+ onClick: () => {},
21
+ label: i19openCart,
22
+ },
23
+ });
24
+ const isSidenavOpen = ref(false);
25
+ </script>
26
+
27
+ <template>
28
+ <StickyHeader>
29
+ <div
30
+ class="container lg:max-w-7xl mx-auto px-1 lg:pl-3
31
+ grid grid-flow-col grid-cols-3 justify-between items-center
32
+ md:grid-cols-none md:auto-cols-max"
33
+ data-header
34
+ >
35
+ <slot name="sidenav-toggle">
36
+ <div class="md:hidden" data-sidenav-toggle>
37
+ <button
38
+ class="px-2 my-1"
39
+ :aria-label="$t.i19toggleMenu"
40
+ @click="isSidenavOpen = !isSidenavOpen"
41
+ >
42
+ <slot name="sidenav-toggle-content">
43
+ <i class="i-menu text-base-500 text-3xl"></i>
44
+ </slot>
45
+ </button>
46
+ <Drawer v-model="isSidenavOpen" class="-ml-1 lg:-ml-3">
47
+ MENU
48
+ </Drawer>
49
+ </div>
50
+ </slot>
51
+ <slot name="logo" />
52
+ <slot name="nav" />
53
+ <slot name="buttons">
54
+ <div
55
+ class="px-2 flex justify-end items-center gap-3 lg:gap-4 text-base-800"
56
+ data-header-buttons
57
+ >
58
+ <slot
59
+ name="button"
60
+ v-for="({ icon, onClick, label }, name) in buttons"
61
+ :key="name"
62
+ v-bind="{ name, icon, onClick }"
63
+ >
64
+ <button
65
+ :class="name === 'account' ? 'hidden sm:block' : null"
66
+ :aria-label="label"
67
+ @click="onClick"
68
+ :data-header-button="name"
69
+ >
70
+ <slot name="button-content" v-bind="{ name, icon }">
71
+ <i
72
+ :class="icon"
73
+ class="hover:text-primary w-7 h-7 hover:scale-110 active:scale-125"
74
+ ></i>
75
+ </slot>
76
+ </button>
77
+ </slot>
78
+ </div>
79
+ </slot>
80
+ </div>
81
+ </StickyHeader>
82
+ </template>