@nuskin/product-components 3.18.0 → 4.0.0-cx15-11969.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.
@@ -1,39 +0,0 @@
1
- <svg id="Layer_1"
2
- xmlns="http://www.w3.org/2000/svg" viewBox="0 0 164 164">
3
- <style>.st0{fill:#fff}.st1{fill:#dadbdb}.st2{fill:#ececec}.st3{fill:#dadbda}</style>
4
- <path class="st0" d="M67.87 136.71V96.66h62.34c3.58 0 6.5 2.92 6.5 6.5v33.55H67.87z"/>
5
- <path class="st1" d="M130.21 97.16c3.31 0 6 2.69 6 6v33.05H68.37V97.16h61.84m0-1H67.37v41.05h69.84v-34.05c0-3.87-3.13-7-7-7z"/>
6
- <path class="st0" d="M67.87 93.96V79.5h65.34c1.93 0 3.5 1.57 3.5 3.5v10.96H67.87z"/>
7
- <path class="st1" d="M133.21 80c1.65 0 3 1.35 3 3v10.46H68.37V80h64.84m0-1H67.37v15.46h69.84V83c0-2.21-1.79-4-4-4z"/>
8
- <path class="st0" d="M67.87 136.71V96.66h62.34c3.58 0 6.5 2.92 6.5 6.5v33.55H67.87z"/>
9
- <path class="st1" d="M130.21 97.16c3.31 0 6 2.69 6 6v33.05H68.37V97.16h61.84m0-1H67.37v41.05h69.84v-34.05c0-3.87-3.13-7-7-7z"/>
10
- <path class="st0" d="M67.87 93.96V79.5h65.34c1.93 0 3.5 1.57 3.5 3.5v10.96H67.87z"/>
11
- <path class="st1" d="M133.21 80c1.65 0 3 1.35 3 3v10.46H68.37V80h64.84m0-1H67.37v15.46h69.84V83c0-2.21-1.79-4-4-4z"/>
12
- <path class="st2" d="M129.63 100.03H67.37v37.18h65.66v-33.78c0-1.87-1.52-3.4-3.4-3.4zM131.33 82.87H67.37v11.58h65.66v-9.88c0-.94-.76-1.7-1.7-1.7z"/>
13
- <path class="st1" d="M130.21 97.16c3.31 0 6 2.69 6 6v33.05H68.37V97.16h61.84m0-1H67.37v41.05h69.84v-34.05c0-3.87-3.13-7-7-7zM133.21 80c1.65 0 3 1.35 3 3v10.46H68.37V80h64.84m0-1H67.37v15.46h69.84V83c0-2.21-1.79-4-4-4z"/>
14
- <path class="st3" d="M129.63 100.03H89.07v9.34h43.96v-5.94c0-1.87-1.52-3.4-3.4-3.4z"/>
15
- <path class="st0" d="M76.37 136.71V124.5h27.56a2.5 2.5 0 0 1 2.5 2.5v9.71H76.37z"/>
16
- <path class="st1" d="M103.93 125c1.1 0 2 .9 2 2v9.21H76.87V125h27.06m0-1H75.87v13.21h31.06V127c0-1.66-1.34-3-3-3z"/>
17
- <path class="st0" d="M76.33 121.8l-7.06-86.11v-8.4h43.99v8.44l-7.07 86.07z"/>
18
- <path class="st1" d="M112.76 27.79v7.9l-7.02 85.6H76.79l-7.02-85.6v-7.9h42.99m1-1H68.77v8.94l7.1 86.56h30.78l7.1-86.56v-8.94h.01z"/>
19
- <path class="st2" d="M109.58 30.67H68.77v5.06l7.1 86.57h26.92l6.79-82.69zM101.9 127.87H75.87v9.34h26.88v-8.49a.85.85 0 0 0-.85-.85z"/>
20
- <path class="st1" d="M103.93 125c1.1 0 2 .9 2 2v9.21H76.87V125h27.06m0-1H75.87v13.21h31.06V127c0-1.66-1.34-3-3-3z"/>
21
- <path class="st3" d="M109.58 30.67H68.77v5.06l.35 4.27h40.42l.04-.39z"/>
22
- <path class="st1" d="M112.76 27.79v7.9l-7.02 85.6H76.79l-7.02-85.6v-7.9h42.99m1-1H68.77v8.94l7.1 86.56h30.78l7.1-86.56v-8.94h.01z"/>
23
- <g>
24
- <path class="st0" d="M27.5 136.71V99.07c0-4.41-.07-8.1-.13-11.36-.35-19.29-.35-19.29 16.62-29.61.15-.09.24-.25.24-.43V43.4c0-1.13.92-2.05 2.05-2.05h14.98c1.13 0 2.05.92 2.05 2.05v14.28c0 .18.1.35.26.44 16.61 9.04 16.6 9.98 16.49 34.13-.01 2.1-.02 4.37-.02 6.83v37.64H27.5z"/>
25
- <path class="st1" d="M61.26 41.85c.85 0 1.55.7 1.55 1.55v14.28c0 .37.2.7.52.88 8.46 4.61 12.37 7.06 14.32 11.2 2 4.27 1.97 10.74 1.92 22.48-.01 2.1-.02 4.37-.02 6.83v37.14H28V99.07c0-4.41-.07-8.11-.13-11.37-.35-19-.35-19 16.38-29.17.3-.18.48-.51.48-.85V43.4c0-.85.7-1.55 1.55-1.55h14.98m0-1H46.28c-1.41 0-2.55 1.14-2.55 2.55v14.28C23.65 69.88 27 68.21 27 99.07v38.14h53.55V99.07c0-30.86 1.6-31.42-16.73-41.4V43.4a2.563 2.563 0 0 0-2.56-2.55z"/>
26
- </g>
27
- <g>
28
- <path class="st2" d="M59.63 59.85V47.27c0-1.41-1.14-2.55-2.55-2.55H43.73v12.95C23.65 69.88 27 68.21 27 99.07v38.14h49.37v-35.96c0-30.86 1.59-31.42-16.74-41.4z"/>
29
- </g>
30
- <g>
31
- <path class="st3" d="M27 124h49.37v13.21H27z"/>
32
- </g>
33
- <g>
34
- <path class="st1" d="M61.26 41.85c.85 0 1.55.7 1.55 1.55v14.28c0 .37.2.7.52.88 8.46 4.61 12.37 7.06 14.32 11.2 2 4.27 1.97 10.74 1.92 22.48-.01 2.1-.02 4.37-.02 6.83v37.14H28V99.07c0-4.41-.07-8.11-.13-11.37-.35-19-.35-19 16.38-29.17.3-.18.48-.51.48-.85V43.4c0-.85.7-1.55 1.55-1.55h14.98m0-1H46.28c-1.41 0-2.55 1.14-2.55 2.55v14.28C23.65 69.88 27 68.21 27 99.07v38.14h53.55V99.07c0-30.86 1.6-31.42-16.73-41.4V43.4a2.563 2.563 0 0 0-2.56-2.55z"/>
35
- </g>
36
- <circle class="st0" cx="53.69" cy="87.41" r="8.41"/>
37
- <circle class="st0" cx="91.26" cy="56.88" r="8.41"/>
38
- <path fill="none" d="M0 0h164v164H0z"/>
39
- </svg>
@@ -1,155 +0,0 @@
1
- <template>
2
- <div>
3
- <NuHomeCloneProductCarousel
4
- :title="title"
5
- :product-ids="productIds"
6
- :country="country"
7
- :language="language"
8
- :force-loading="loading"
9
- referrer="product_recommendation_carousel"
10
- @click-pdp="onClickPdp"
11
- @click-atc="onClickAddToCart"
12
- />
13
- </div>
14
- </template>
15
-
16
- <script>
17
- import { CartService } from "@nuskin/ns-shop";
18
- import { events } from "@nuskin/ns-util";
19
- import {
20
- getPersonalizedRecommendations,
21
- getRelatedProducts
22
- } from "../services/NsProductRecommendationClient";
23
- import NuHomeCloneProductCarousel from "./NuHomeCloneProductCarousel/NuHomeCloneProductCarousel.vue";
24
-
25
- export default {
26
- name: "NsProductRecsCarousel",
27
- components: { NuHomeCloneProductCarousel },
28
- props: {
29
- title: {
30
- type: String,
31
- default: ""
32
- },
33
- productId: {
34
- type: String,
35
- default: ""
36
- },
37
- language: {
38
- type: String,
39
- required: true
40
- },
41
- country: {
42
- type: String,
43
- required: true
44
- }
45
- },
46
- data() {
47
- return {
48
- loading: false,
49
- recommendedProductIds: [],
50
- productIdsToOmit: [],
51
- productsLimit: 10
52
- };
53
- },
54
- computed: {
55
- productIds() {
56
- // Filter out all products marked for omission
57
- return this.recommendedProductIds.filter(
58
- id => !this.productIdsToOmit.includes(id)
59
- );
60
- }
61
- },
62
- watch: {
63
- /**
64
- * @param {string | undefined} id
65
- */
66
- productId(id) {
67
- this.initRecommendations(id);
68
- }
69
- },
70
- created() {
71
- // When items are added to the cart, omit them from recommendations.
72
- events.subscribe(events.shop.CART_UPDATED, info => {
73
- if (info.add) {
74
- this.productIdsToOmit.push(info.add.item.sku);
75
- }
76
- });
77
-
78
- // Get the current status of the cart-data-sync process,
79
- // and subscribe to any further changes to that status.
80
- events.getValue(
81
- events.shop.CART_SYNCED_ON_LOAD,
82
- status => {
83
- // Abort if the cart hasn't been synced yet,
84
- // and wait for the next sync event.
85
- if (!status) return;
86
-
87
- // Cart data has been synced; get current cart contents and
88
- // set as the list of products to omit from recommendations.
89
- const cartItems = CartService.getItemData() || [];
90
- const cartSkus = cartItems.map(item => item.sku);
91
- this.productIdsToOmit = cartSkus;
92
- },
93
- true
94
- );
95
- },
96
- mounted() {
97
- this.initRecommendations(this.productId);
98
- },
99
- methods: {
100
- /**
101
- * @param {{
102
- * sku: string,
103
- * slug: string
104
- * }} pdpEvent
105
- */
106
- onClickPdp(pdpEvent) {
107
- // TODO: emit GTM event
108
- console.log("pdpEvent:", pdpEvent);
109
- },
110
- /**
111
- * @param {{
112
- * sku: string,
113
- * qty: number,
114
- * userId: string,
115
- * cntryCd: string,
116
- * isAdr: boolean,
117
- * referrer: string,
118
- * domain: string
119
- * }} atcEvent
120
- */
121
- onClickAddToCart(atcEvent) {
122
- // TODO: emit GTM event
123
- console.log("atcEvent", atcEvent);
124
- },
125
- /**
126
- * @param {string} [productId]
127
- */
128
- async initRecommendations(productId) {
129
- this.loading = true;
130
-
131
- try {
132
- let productIds = [];
133
- if (productId) {
134
- // Related Products mode
135
- productIds = await getRelatedProducts(productId, this.productsLimit);
136
- } else {
137
- // User-Personalized mode
138
- productIds = await getPersonalizedRecommendations(this.productsLimit);
139
- }
140
- this.recommendedProductIds = productIds;
141
- } catch (err) {
142
- console.error(err);
143
- }
144
-
145
- this.loading = false;
146
- }
147
- }
148
- };
149
- </script>
150
-
151
- <style>
152
- .content {
153
- padding: 0;
154
- }
155
- </style>
@@ -1,209 +0,0 @@
1
- <template>
2
- <div class="swiper" data-carousel="carousel">
3
- <slot />
4
- </div>
5
- </template>
6
- <script>
7
- import Swiper, { Navigation, Pagination } from "swiper";
8
- import "swiper/swiper.scss";
9
- import "swiper/modules/pagination/pagination.scss";
10
-
11
- export const CSS_CLASSES = {
12
- SWIPER_WRAPPER: "swiper-wrapper",
13
- SWIPER_NAV_PREV: "swiper-button-prev",
14
- SWIPER_NAV_NEXT: "swiper-button-next",
15
- SWIPER_SLIDE: "swiper-slide",
16
- SWIPER_PAGINATION: "swiper-pagination",
17
- SWIPER_VISIBLE: "swiper-slide-visible",
18
- SWIPER_DUPLICATE: "swiper-slide-duplicate"
19
- };
20
-
21
- export const SELECTORS = {
22
- WRAPPER: '[data-carousel="wrapper"]',
23
- CHEVRON_LEFT: '[data-carousel="chevron-left"]',
24
- CHEVRON_RIGHT: '[data-carousel="chevron-right"]',
25
- ITEMS: '[data-carousel="item"]',
26
- DISABLED_TAB: "[data-disabletab]",
27
- DOTS: '[data-carousel="dots"]',
28
- DOT_ELEMENT: "span"
29
- };
30
-
31
- export default {
32
- name: "Carousel",
33
- props: {
34
- options: {
35
- default: () => ({}),
36
- type: Object
37
- }
38
- },
39
- data() {
40
- return {
41
- swiper: {
42
- type: Object,
43
- default: undefined
44
- }
45
- };
46
- },
47
- computed: {
48
- carouselWrapper() {
49
- return this.$el.querySelector(SELECTORS.WRAPPER);
50
- },
51
- carouselChevrons() {
52
- return [
53
- this.$el.querySelector(SELECTORS.CHEVRON_LEFT),
54
- this.$el.querySelector(SELECTORS.CHEVRON_RIGHT)
55
- ];
56
- },
57
- carouselItems() {
58
- return this.$el.querySelectorAll(SELECTORS.ITEMS);
59
- },
60
- carouselDotContainer() {
61
- return this.$el.querySelector(SELECTORS.DOTS);
62
- },
63
- carouselDots() {
64
- return this.$el.querySelectorAll(
65
- `.${CSS_CLASSES.SWIPER_PAGINATION} ${SELECTORS.DOT_ELEMENT}`
66
- );
67
- }
68
- },
69
- mounted() {
70
- this.setSwiperClasses();
71
- const options = this.buildOptions();
72
- this.swiper = new Swiper(this.$el, options);
73
- this.bindEvents();
74
- this.toggleTabItemIndex();
75
- this.setDotsTabIndex();
76
-
77
- this.swiper.on("slideChange", () => {
78
- this.toggleTabItemIndex();
79
- });
80
- },
81
- methods: {
82
- toggleTabItemIndex() {
83
- /**
84
- * Set all carousel slides, duplicates, and their anchor tags to be non-tabbable.
85
- * Note: We are using `methods` here instead of `computed` to fetch the updated DOM after carousel's slideChange
86
- */
87
- const carouselItems = this.getCarouselItems();
88
- const duplicateCarouselItems = this.getDuplicateCarouselItems();
89
- const visibleCarouselItems = this.getVisibleCarouselItems();
90
-
91
- [...carouselItems, ...duplicateCarouselItems].forEach(el => {
92
- el.tabIndex = "-1";
93
-
94
- const links = el.querySelectorAll("a");
95
- links.forEach(link => {
96
- link.tabIndex = "-1";
97
- });
98
- });
99
-
100
- /**
101
- * Set all visible slides and their anchor tags (with no `data-disabletab`) to be tabbable.
102
- */
103
- visibleCarouselItems.forEach(el => {
104
- if (el.firstChild instanceof HTMLAnchorElement) {
105
- el.firstChild.tabIndex = "0";
106
- } else {
107
- el.tabIndex = "0";
108
- }
109
-
110
- const links = el.querySelectorAll(`a:not(${SELECTORS.DISABLED_TAB})`);
111
- links.forEach(link => {
112
- link.tabIndex = "0";
113
- });
114
- });
115
- },
116
- setDotsTabIndex() {
117
- this.carouselDots.forEach(dot => {
118
- dot.tabIndex = "0";
119
- });
120
- },
121
- getCarouselItems() {
122
- return this.$el.querySelectorAll(SELECTORS.ITEMS);
123
- },
124
- getDuplicateCarouselItems() {
125
- return this.$el.querySelectorAll(
126
- `.${CSS_CLASSES.SWIPER_DUPLICATE}${SELECTORS.ITEMS}`
127
- );
128
- },
129
- getVisibleCarouselItems() {
130
- return this.$el.querySelectorAll(
131
- `.${CSS_CLASSES.SWIPER_VISIBLE}${SELECTORS.ITEMS}:not(${SELECTORS.DISABLED_TAB})`
132
- );
133
- },
134
- setSwiperClasses() {
135
- const {
136
- SWIPER_WRAPPER,
137
- SWIPER_NAV_PREV,
138
- SWIPER_NAV_NEXT,
139
- SWIPER_SLIDE,
140
- SWIPER_PAGINATION
141
- } = CSS_CLASSES;
142
- if (this.carouselWrapper)
143
- this.carouselWrapper.classList.add(SWIPER_WRAPPER);
144
-
145
- this.carouselItems.forEach(carouselItem => {
146
- carouselItem.classList.add(SWIPER_SLIDE);
147
- });
148
-
149
- if (this.carouselDotContainer)
150
- this.carouselDotContainer.classList.add(SWIPER_PAGINATION);
151
-
152
- const [left, right] = this.carouselChevrons;
153
- if (left) left.classList.add(SWIPER_NAV_PREV);
154
- if (right) right.classList.add(SWIPER_NAV_NEXT);
155
- },
156
- buildOptions() {
157
- const { options } = this;
158
- return {
159
- ...options,
160
- modules: [Navigation, Pagination]
161
- };
162
- },
163
- bindEvents() {
164
- const events = ["click"];
165
- events.forEach(event => {
166
- this.swiper.on(event, (swiperEvent, nativeEvent) =>
167
- this.$emit(event, { swiperEvent, nativeEvent })
168
- );
169
- });
170
-
171
- this.carouselDots.forEach(dot => {
172
- dot.addEventListener("keypress", e => {
173
- if (e.key === "Enter") e.target.click();
174
- });
175
- });
176
- }
177
- }
178
- };
179
- </script>
180
- <style lang="scss">
181
- .swiper-pagination {
182
- position: static;
183
- margin-top: 1.25rem;
184
-
185
- .swiper-pagination-bullet {
186
- height: 10px;
187
- width: 10px;
188
- margin: 5px 7px;
189
-
190
- &.swiper-pagination-bullet-active {
191
- background-color: #869791;
192
- }
193
- }
194
- }
195
-
196
- .carousel-chevron {
197
- .swiper-button-prev,
198
- .swiper-button-next {
199
- position: static;
200
- right: initial;
201
- left: initial;
202
-
203
- &::after {
204
- content: "";
205
- display: none;
206
- }
207
- }
208
- }
209
- </style>
@@ -1,93 +0,0 @@
1
- <template>
2
- <div data-carousel="chevron" class="carousel-chevron">
3
- <a data-carousel="chevron-left" class="arrow-left effect-black" href>
4
- <svg
5
- viewBox="0 0 24 24"
6
- preserveAspectRatio="xMidYMid meet"
7
- focusable="false"
8
- size="icon-sm"
9
- class="icon"
10
- icon-size="icon-lg"
11
- style="pointer-events: none; display: block;"
12
- >
13
- <g
14
- id="icon-narrow-angle-left-24"
15
- stroke="none"
16
- stroke-width="1"
17
- fill="none"
18
- fill-rule="evenodd"
19
- stroke-linecap="round"
20
- stroke-linejoin="round"
21
- >
22
- <g transform="translate(-196, -226)" stroke="currentColor">
23
- <polyline
24
- transform="translate(209.000000, 237.500000) scale(-1.2, 1.2) rotate(90.000000) translate(-209.000000, -237.500000) "
25
- points="200 242 209 233 218 242"
26
- />
27
- </g>
28
- </g>
29
- </svg>
30
- </a>
31
- <a data-carousel="chevron-right" class="arrow-right effect-black" href>
32
- <svg
33
- viewBox="0 0 24 24"
34
- preserveAspectRatio="xMidYMid meet"
35
- focusable="false"
36
- size="icon-sm"
37
- class="icon"
38
- icon-size="icon-lg"
39
- style="pointer-events: none; display: block;"
40
- >
41
- <g
42
- id="icon-narrow-angle-right-24"
43
- stroke="none"
44
- stroke-width="1"
45
- fill="none"
46
- fill-rule="evenodd"
47
- stroke-linecap="round"
48
- stroke-linejoin="round"
49
- >
50
- <g transform="translate(-196, -226)" stroke="currentColor">
51
- <polyline
52
- transform="translate(209.000000, 237.500000) scale(-1.2, 1.2) rotate(-90.000000) translate(-209.000000, -237.500000) "
53
- points="200 242 209 233 218 242"
54
- />
55
- </g>
56
- </g>
57
- </svg>
58
- </a>
59
- </div>
60
- </template>
61
- <script>
62
- export default {
63
- name: "CarouselChevron"
64
- };
65
- </script>
66
- <style lang="scss">
67
- .carousel-chevron {
68
- display: flex;
69
- flex-wrap: wrap;
70
- gap: 20px;
71
-
72
- .arrow-left,
73
- .arrow-right {
74
- height: auto;
75
- width: auto;
76
- padding: 10px;
77
- border: 2px solid black;
78
- border-radius: 3px;
79
- cursor: pointer;
80
- color: inherit !important;
81
-
82
- svg {
83
- height: 20px;
84
- width: 20px;
85
-
86
- &:hover {
87
- fill: var(--theme__color3);
88
- color: var(--theme__color3);
89
- }
90
- }
91
- }
92
- }
93
- </style>
@@ -1,72 +0,0 @@
1
- <template>
2
- <div class="preloader">
3
- <div class="loader"></div>
4
- </div>
5
- </template>
6
-
7
- <script>
8
- export default {
9
- name: "Loader"
10
- };
11
- </script>
12
-
13
- <style scoped lang="scss">
14
- .preloader {
15
- position: absolute;
16
- top: 0;
17
- left: 0;
18
- width: 100%;
19
- height: 100%;
20
- z-index: 10;
21
-
22
- .loader {
23
- display: inline-block;
24
- position: relative;
25
- width: 9.375rem;
26
- height: 9.375rem;
27
- border-radius: 50%;
28
- border: 3px solid transparent;
29
- border-top-color: #9370db;
30
- animation: spin 2s linear infinite;
31
- left: 50%;
32
- top: 50%;
33
- margin: -4.7rem 0 0 -4.7rem;
34
-
35
- &::before,
36
- &::after {
37
- content: " ";
38
- position: absolute;
39
- border-radius: 50%;
40
- border: 3px solid transparent;
41
- }
42
-
43
- &::before {
44
- top: 5px;
45
- left: 5px;
46
- right: 5px;
47
- bottom: 5px;
48
- border-top-color: #ba55d3;
49
- animation: spin 3s linear infinite;
50
- }
51
-
52
- &::after {
53
- top: 15px;
54
- left: 15px;
55
- right: 15px;
56
- bottom: 15px;
57
- border-top-color: #f56767;
58
- animation: spin 1.5s linear infinite;
59
- }
60
- }
61
- }
62
-
63
- @keyframes spin {
64
- 0% {
65
- transform: rotate(0deg);
66
- }
67
-
68
- 100% {
69
- transform: rotate(360deg);
70
- }
71
- }
72
- </style>