@wayke-se/components-react 3.5.3 → 3.6.0-beta.1

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 (47) hide show
  1. package/README.md +51 -43
  2. package/dist-node/index.js +692 -128
  3. package/dist-node/index.js.map +1 -1
  4. package/dist-src/components/AccessoryCard/index.js +14 -0
  5. package/dist-src/components/AccessoryCard/wrapper.js +90 -0
  6. package/dist-src/components/DocumentList/wrapper.js +1 -1
  7. package/dist-src/components/Gallery/index.js +7 -4
  8. package/dist-src/components/Gallery/wrapper.js +71 -39
  9. package/dist-src/components/Icon/index.js +2 -0
  10. package/dist-src/components/Image/index.js +5 -0
  11. package/dist-src/components/Link/index.js +28 -0
  12. package/dist-src/components/NavButton/index.js +42 -0
  13. package/dist-src/components/OverflowGrid/index.js +56 -66
  14. package/dist-src/components/OverflowGrid/wrapper.js +144 -0
  15. package/dist-src/components/PriceBox/index.js +6 -0
  16. package/dist-src/components/PriceBox/wrapper.js +34 -0
  17. package/dist-src/layout/theme.js +8 -0
  18. package/dist-src/layouts/searchItem/Accessories/AccessoryModal.js +51 -0
  19. package/dist-src/layouts/searchItem/Accessories/index.js +32 -0
  20. package/dist-src/layouts/searchItem/Related.js +23 -25
  21. package/dist-src/layouts/searchItem/index.js +3 -1
  22. package/dist-src/queries/SEARCH_ITEM_BRANCH_QUERY.js +18 -0
  23. package/dist-src/queries/SEARCH_ITEM_QUERY.js +18 -0
  24. package/dist-types/@types/codegen/types.d.ts +17 -0
  25. package/dist-types/components/AccessoryCard/index.d.ts +16 -0
  26. package/dist-types/components/AccessoryCard/wrapper.d.ts +18 -0
  27. package/dist-types/components/Gallery/wrapper.d.ts +2 -6
  28. package/dist-types/components/Icon/index.d.ts +1 -0
  29. package/dist-types/components/Image/index.d.ts +1 -0
  30. package/dist-types/components/Link/index.d.ts +7 -0
  31. package/dist-types/components/NavButton/index.d.ts +3 -0
  32. package/dist-types/components/OverflowGrid/index.d.ts +12 -3
  33. package/dist-types/components/OverflowGrid/wrapper.d.ts +18 -0
  34. package/dist-types/components/PriceBox/index.d.ts +11 -0
  35. package/dist-types/components/PriceBox/wrapper.d.ts +10 -0
  36. package/dist-types/layout/theme.d.ts +8 -0
  37. package/dist-types/layouts/searchItem/Accessories/AccessoryModal.d.ts +8 -0
  38. package/dist-types/layouts/searchItem/Accessories/index.d.ts +7 -0
  39. package/dist-web/index.js +605 -123
  40. package/dist-web/index.js.map +1 -1
  41. package/package.json +2 -4
  42. package/assets/ajax-loader.gif +0 -0
  43. package/assets/default.css +0 -1
  44. package/assets/fonts/slick.eot +0 -0
  45. package/assets/fonts/slick.svg +0 -14
  46. package/assets/fonts/slick.ttf +0 -0
  47. package/assets/fonts/slick.woff +0 -0
@@ -0,0 +1,14 @@
1
+ import React from 'react';
2
+ import { Wrapper, Image, ImageaPlaceholder, Body, Heading, Title, Branding, Price, Preamble, ReadMoreBtn, } from './wrapper';
3
+ import { IconImage } from '../Icon/index';
4
+ const AccessoryCard = ({ title, image, branding, price, preamble, readMoreCta, }) => (React.createElement(Wrapper, null,
5
+ image ? (React.createElement(Image, { src: image.src, srcSet: image.srcSet, alt: image.alt })) : (React.createElement(ImageaPlaceholder, null,
6
+ React.createElement(IconImage, null))),
7
+ React.createElement(Body, null,
8
+ React.createElement(Heading, null,
9
+ React.createElement(Title, null, title),
10
+ branding && React.createElement(Branding, { src: branding.src, srcSet: branding.srcSet, alt: branding.alt })),
11
+ price && React.createElement(Price, null, price),
12
+ preamble && React.createElement(Preamble, null, preamble),
13
+ readMoreCta && React.createElement(ReadMoreBtn, { onClick: readMoreCta }, "L\u00E4s mer"))));
14
+ export default AccessoryCard;
@@ -0,0 +1,90 @@
1
+ import styled, { css } from 'styled-components';
2
+ import { size } from '../../layout/helpers';
3
+ import { ButtonReset } from '../Button/index';
4
+ export const Wrapper = styled.div `
5
+ display: flex;
6
+ flex-direction: column;
7
+ gap: ${size(2)};
8
+ height: 100%;
9
+ `;
10
+ const imageBaseStyling = css `
11
+ flex-shrink: 0;
12
+ aspect-ratio: 16 / 9;
13
+ border-radius: 3px;
14
+ `;
15
+ export const Image = styled.img `
16
+ ${imageBaseStyling};
17
+ display: block;
18
+ width: 100%;
19
+ object-fit: cover;
20
+ `;
21
+ export const ImageaPlaceholder = styled.div `
22
+ ${imageBaseStyling};
23
+ display: flex;
24
+ align-items: center;
25
+ justify-content: center;
26
+ color: ${(props) => props.theme.color.textDarkLighten};
27
+ font-size: 2rem;
28
+ background-color: ${(props) => props.theme.color.accent};
29
+ `;
30
+ export const Body = styled.div `
31
+ flex: 1 1 auto;
32
+ display: flex;
33
+ align-items: flex-start;
34
+ flex-direction: column;
35
+ gap: ${size(1)};
36
+ `;
37
+ export const Heading = styled.div `
38
+ display: flex;
39
+ align-items: center;
40
+ justify-content: space-between;
41
+ gap: ${size(2)};
42
+ `;
43
+ export const Title = styled.div.attrs(() => ({
44
+ className: 'wayke__theme wayke__font--bold',
45
+ })) `
46
+ font-size: 1.125rem;
47
+ `;
48
+ export const Branding = styled.img `
49
+ display: block;
50
+ `;
51
+ export const Price = styled.div.attrs(() => ({
52
+ className: 'wayke__theme wayke__font--bold',
53
+ })) ``;
54
+ export const Preamble = styled.div `
55
+ --preamble-max-height: ${size(6)};
56
+ --preamble-gradient-height: calc(var(--preamble-max-height) / 2);
57
+
58
+ position: relative;
59
+ max-height: var(--preamble-max-height);
60
+ overflow: hidden;
61
+ display: -webkit-box;
62
+ -webkit-box-orient: vertical;
63
+ -webkit-line-clamp: 2;
64
+ white-space: pre-wrap;
65
+
66
+ &::before {
67
+ content: '';
68
+ position: absolute;
69
+ top: var(--preamble-max-height);
70
+ left: 0;
71
+ width: 100%;
72
+ height: var(--preamble-gradient-height);
73
+ transform: translateY(-100%); // Only visible if Preamble reaches max height
74
+ color: ${(props) => props.theme.color.bg};
75
+ mask-image: ${(props) => props.theme.mask.gradient.toTop};
76
+ pointer-events: none;
77
+ }
78
+ `;
79
+ export const ReadMoreBtn = styled(ButtonReset).attrs(() => ({
80
+ className: 'wayke__theme wayke__font--bold wayke__color--primary-text',
81
+ })) `
82
+ margin-top: auto;
83
+ display: block;
84
+ color: ${(props) => props.theme.color.link};
85
+ font-size: 0.875rem;
86
+
87
+ &:hover {
88
+ text-decoration: underline;
89
+ }
90
+ `;
@@ -38,7 +38,7 @@ export const PdfSubtitle = styled.div `
38
38
  color: ${(props) => props.theme.color.textDarkLighten};
39
39
  `;
40
40
  export const PdfColumn = styled.div `
41
- flex 0 0 auto;
41
+ flex: 0 0 auto;
42
42
  &:first-child {
43
43
  flex: 1 1 auto;
44
44
  }
@@ -4,6 +4,7 @@ import scrollIntoView from 'scroll-into-view-if-needed';
4
4
  import { Wrapper, SliderWrapper, Item, Image, ArrowLeft, ArrowRight, Main, Alt, QuickNav, QuickNavItem, QuickNavBtn, QuickNavImg, EnableNavigationButton, } from './wrapper';
5
5
  import { IconChevronLeft, IconChevronRight } from '../Icon/index';
6
6
  import { ButtonSecondary, ButtonContent } from '../Button/index';
7
+ import { NavButton } from '../NavButton/index';
7
8
  import Lightbox from '../Lightbox/index';
8
9
  import EmbededVideo from '../Video/EmbededVideo';
9
10
  import QuickNavEmbeded from '../Video/QuickNavEmbeded';
@@ -97,10 +98,12 @@ const Gallery = ({ media, placeholderImage }) => {
97
98
  React.createElement(ButtonSecondary, { onClick: onEnableNavigation, title: "St\u00E4ng" },
98
99
  React.createElement(ButtonContent, null, "St\u00E4ng"))))),
99
100
  !navigationDisabled && mediaLength > 1 && (React.createElement(React.Fragment, null,
100
- React.createElement(ArrowLeft, { onClick: prevImage, title: "F\u00F6reg\u00E5ende bild" },
101
- React.createElement(IconChevronLeft, { block: true })),
102
- React.createElement(ArrowRight, { onClick: nextImage, title: "N\u00E4sta bild" },
103
- React.createElement(IconChevronRight, { block: true }))))),
101
+ React.createElement(ArrowLeft, null,
102
+ React.createElement(NavButton, { onClick: prevImage, title: "F\u00F6reg\u00E5ende bild" },
103
+ React.createElement(IconChevronLeft, { block: true }))),
104
+ React.createElement(ArrowRight, null,
105
+ React.createElement(NavButton, { onClick: nextImage, title: "N\u00E4sta bild" },
106
+ React.createElement(IconChevronRight, { block: true })))))),
104
107
  React.createElement(Alt, null,
105
108
  React.createElement(QuickNav, { ref: quickNavRef }, !!media?.length ? (media.map((m, i) => {
106
109
  const src = m.files[0].formats.filter(notEmpty).find((x) => x.format === '225x150')?.url ||
@@ -99,6 +99,76 @@ export const SliderWrapper = styled.div `
99
99
  bottom: 0;
100
100
  left: 0;
101
101
  right: 0;
102
+ user-select: none;
103
+ touch-action: pan-y;
104
+ -webkit-tap-highlight-color: transparent;
105
+
106
+ .slick-list,
107
+ .slick-track {
108
+ transform: translate3d(0, 0, 0);
109
+ }
110
+ }
111
+
112
+ .slick-list {
113
+ position: relative;
114
+ display: block;
115
+ margin: 0;
116
+ padding: 0;
117
+ overflow: hidden;
118
+
119
+ &:focus {
120
+ outline: none;
121
+ }
122
+
123
+ &.dragging {
124
+ cursor: pointer;
125
+ cursor: hand;
126
+ }
127
+ }
128
+
129
+ .slick-track {
130
+ position: relative;
131
+ top: 0;
132
+ left: 0;
133
+ display: block;
134
+ margin-left: auto;
135
+ margin-right: auto;
136
+
137
+ &::before,
138
+ &::after {
139
+ content: '';
140
+ display: table;
141
+ }
142
+
143
+ &::after {
144
+ clear: both;
145
+ }
146
+ }
147
+
148
+ .slick-slide {
149
+ display: none;
150
+ float: left;
151
+ min-height: 1px;
152
+ }
153
+
154
+ .slick-loading {
155
+ .slick-track {
156
+ visibility: hidden;
157
+ }
158
+
159
+ img {
160
+ display: none;
161
+ }
162
+ }
163
+
164
+ .slick-initialized {
165
+ .slick-slide {
166
+ display: block;
167
+ }
168
+ }
169
+
170
+ .slick-slide.dragging img {
171
+ pointer-events: none;
102
172
  }
103
173
 
104
174
  ${(props) => props.theme.breakpoint.LtMd} {
@@ -111,7 +181,6 @@ export const SliderWrapper = styled.div `
111
181
 
112
182
  .slick-slide {
113
183
  border-right: ${size(1)} solid ${(props) => props.theme.color.bg};
114
- //transform: scale(0.95);
115
184
  transform-origin: 0 50%;
116
185
  transition: transform 150ms ease;
117
186
  }
@@ -149,47 +218,10 @@ export const ImageFull = styled.img `
149
218
  object-fit: cover;
150
219
  `;
151
220
  // Arrow Nav
152
- const Arrow = styled(ButtonReset) `
221
+ const Arrow = styled.div `
153
222
  position: absolute;
154
223
  top: 50%;
155
224
  transform: translateY(-50%);
156
- display: flex;
157
- align-items: center;
158
- justify-content: center;
159
- width: ${size(4)};
160
- height: ${size(4)};
161
- border-radius: 50%;
162
- font-size: 1rem;
163
- line-height: 1;
164
- background-color: rgba(255, 255, 255, 0.4);
165
- backdrop-filter: blur(5px);
166
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
167
- color: ${(props) => props.theme.color.textDark};
168
- transform-origin: 50% 50%;
169
- transition: transform 200ms ease;
170
-
171
- :before {
172
- content: '';
173
- position: absolute;
174
- top: 0;
175
- bottom: 0;
176
- left: 0;
177
- right: 0;
178
- border-radius: 50%;
179
- box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
180
- opacity: 0;
181
- transition: opacity 200ms ease;
182
- }
183
-
184
- :hover {
185
- :before {
186
- opacity: 1;
187
- }
188
- }
189
-
190
- :active {
191
- transform: translateY(-50%) scale(0.95);
192
- }
193
225
 
194
226
  ${(props) => props.theme.breakpoint.LtSm} {
195
227
  display: none;
@@ -34,3 +34,5 @@ export const IconExclamationCircle = ({ block }) => (React.createElement(Icon, {
34
34
  React.createElement("path", { d: "M14.482 21.893c0-0.857 0.694-1.551 1.551-1.551s1.551 0.694 1.551 1.551c0 0.857-0.694 1.551-1.551 1.551s-1.551-0.694-1.551-1.551zM16.033 2.838c-7.271 0-13.187 5.916-13.187 13.187s5.916 13.187 13.187 13.187 13.187-5.916 13.187-13.187c0-7.271-5.916-13.187-13.187-13.187zM16.033 27.203c-6.163 0-11.178-5.015-11.178-11.178s5.015-11.178 11.178-11.178c6.164 0 11.178 5.015 11.178 11.178s-5.014 11.178-11.178 11.178zM16.033 8.308c-0.555 0-1.004 0.45-1.004 1.004v8.227c0 0.555 0.45 1.004 1.004 1.004s1.004-0.45 1.004-1.004v-8.227c0-0.555-0.45-1.004-1.004-1.004z" })));
35
35
  export const IconExclamationTriangle = ({ block }) => (React.createElement(Icon, { viewBox: "0 0 32 32", block: block },
36
36
  React.createElement("path", { d: "M15.951 19.663c-0.457 0-0.828-0.37-0.828-0.828v-4.357c0-0.457 0.37-0.828 0.828-0.828s0.828 0.37 0.828 0.828v4.357c0 0.457-0.371 0.828-0.828 0.828zM15.952 22.906c-0.305 0-0.606-0.126-0.821-0.341s-0.338-0.514-0.338-0.818 0.122-0.606 0.338-0.821c0.431-0.43 1.209-0.43 1.639 0 0.215 0.215 0.341 0.516 0.341 0.821s-0.126 0.603-0.341 0.818c-0.215 0.215-0.513 0.341-0.818 0.341zM27.049 27.070h-22.196c-0.352 0-0.677-0.186-0.855-0.489s-0.184-0.677-0.014-0.985l11.098-20.105c0.175-0.317 0.508-0.513 0.87-0.513s0.695 0.197 0.87 0.513l11.098 20.105c0.17 0.308 0.165 0.683-0.014 0.985s-0.504 0.489-0.856 0.489zM6.536 25.083h18.83l-9.415-17.056-9.415 17.056z" })));
37
+ export const IconImage = ({ block }) => (React.createElement(Icon, { viewBox: "0 0 16 16", block: block },
38
+ React.createElement("path", { d: "M14.4 1.6H1.6C.7 1.6 0 2.3 0 3.2v9.6c0 .9.7 1.6 1.6 1.6h12.8c.9 0 1.6-.7 1.6-1.6V3.2c0-.9-.7-1.6-1.6-1.6zm0 11.2H1.6V3.2h12.8v9.6zM3.2 6c0-.7.5-1.2 1.2-1.2s1.2.5 1.2 1.2-.5 1.2-1.2 1.2S3.2 6.7 3.2 6zm.2 4.5l6.2-4.4c.4-.3.9-.2 1.1.2v.1l2.4 4.2c.1.2 0 .4-.1.5-.1 0-.1.1-.2.1H3.7c-.2 0-.4-.2-.4-.4 0-.1 0-.3.1-.3z", fillRule: "evenodd", clipRule: "evenodd" })));
@@ -0,0 +1,5 @@
1
+ import styled from 'styled-components';
2
+ export const Image = styled.img `
3
+ display: block;
4
+ width: 100%;
5
+ `;
@@ -0,0 +1,28 @@
1
+ import styled, { css } from 'styled-components';
2
+ export const Link = styled.a.attrs(() => ({
3
+ className: 'wayke__theme wayke__color--primary-text',
4
+ })) `
5
+ text-decoration: none;
6
+ cursor: pointer;
7
+ text-decoration: underline;
8
+
9
+ :not(:hover) {
10
+ color: ${(props) => props.theme.color.textDark};
11
+ }
12
+
13
+ &:hover {
14
+ text-decoration: underline;
15
+ }
16
+
17
+ ${({ $hoverGhost }) => $hoverGhost &&
18
+ css `
19
+ &:before {
20
+ content: '';
21
+ position: absolute;
22
+ top: 0;
23
+ left: 0;
24
+ width: 100%;
25
+ height: 100%;
26
+ }
27
+ `}
28
+ `;
@@ -0,0 +1,42 @@
1
+ import styled from 'styled-components';
2
+ import { size } from '../../layout/helpers';
3
+ import { ButtonReset } from '../Button/index';
4
+ export const NavButton = styled(ButtonReset) `
5
+ position: relative;
6
+ display: flex;
7
+ align-items: center;
8
+ justify-content: center;
9
+ width: ${size(4)};
10
+ height: ${size(4)};
11
+ border-radius: 50%;
12
+ background-color: ${(props) => props.theme.color.bg};
13
+ color: ${(props) => props.theme.color.textDark};
14
+ font-size: 0.75rem;
15
+ box-shadow: 0 1px 5px rgba(0, 0, 0, 0.2);
16
+ transition: transform 200ms ease;
17
+
18
+ &::before {
19
+ content: '';
20
+ position: absolute;
21
+ top: 0;
22
+ bottom: 0;
23
+ left: 0;
24
+ right: 0;
25
+ border-radius: 50%;
26
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
27
+ opacity: 0;
28
+ transition: opacity 200ms ease;
29
+ }
30
+
31
+ &:enabled {
32
+ &:hover {
33
+ &::before {
34
+ opacity: 1;
35
+ }
36
+ }
37
+ }
38
+
39
+ &:active {
40
+ transform: scale(0.95);
41
+ }
42
+ `;
@@ -1,66 +1,56 @@
1
- import styled from 'styled-components';
2
- import { size } from '../../layout/helpers';
3
- import { Wrapper as Container } from '../Container/wrapper';
4
- export const OverflowGrid = styled.div `
5
- ${(props) => props.theme.breakpoint.LtMd} {
6
- ${Container} & {
7
- margin-left: ${size(-3)};
8
- margin-right: ${size(-2)};
9
- }
10
- }
11
-
12
- ${(props) => props.theme.breakpoint.LtSm} {
13
- ${Container} & {
14
- margin-left: ${size(-2)};
15
- margin-right: ${size(-1)};
16
- }
17
- }
18
- `;
19
- export const OverflowGridList = styled.ul `
20
- display: flex;
21
- align-items: flex-start;
22
- list-style: none;
23
- padding: 0;
24
- margin: ${size(-1)};
25
-
26
- ${(props) => props.theme.breakpoint.LtMd} {
27
- ${Container} & {
28
- overflow: auto;
29
- -webkit-overflow-scrolling: touch;
30
- padding: 0 ${size(3)};
31
-
32
- :after {
33
- content: '';
34
- flex: 0 0 auto;
35
- height: 1px;
36
- width: ${size(2)};
37
- }
38
- }
39
- }
40
-
41
- ${(props) => props.theme.breakpoint.LtSm} {
42
- ${Container} & {
43
- padding: 0 ${size(2)};
44
-
45
- :after {
46
- width: ${size(1)};
47
- }
48
- }
49
- }
50
- `;
51
- export const OverflowGridItem = styled.li `
52
- flex: 1 0 auto;
53
- width: calc(100% - ${size(2)});
54
- max-width: calc(100% - ${size(2)});
55
- padding: ${size(1)};
56
-
57
- ${(props) => props.theme.breakpoint.Sm} {
58
- width: calc(50% - ${size(3)});
59
- max-width: calc(50% - ${size(3)});
60
- }
61
-
62
- ${(props) => props.theme.breakpoint.Md} {
63
- width: 33.333%;
64
- max-width: 33.333%;
65
- }
66
- `;
1
+ import React, { useRef, useCallback, useState, useEffect } from 'react';
2
+ import { Wrapper, ListWrapper, List, Item, PrevBtn, NextBtn } from './wrapper';
3
+ import { IconChevronLeft, IconChevronRight } from '../Icon/index';
4
+ import { NavButton } from '../NavButton/index';
5
+ const OverflowGrid = ({ items, itemKeyBase, spacing, columns, columnsSm, columnsMd, accentBg, }) => {
6
+ const overflowElement = useRef(null);
7
+ const onPrev = useCallback(() => {
8
+ const itemWidth = overflowElement.current?.children[0].clientWidth || 0;
9
+ const scrollLeft = overflowElement.current?.scrollLeft || 0;
10
+ if (scrollLeft > 0) {
11
+ overflowElement.current?.scroll({
12
+ left: scrollLeft - itemWidth,
13
+ behavior: 'smooth',
14
+ });
15
+ }
16
+ }, []);
17
+ const onNext = useCallback(() => {
18
+ const itemWidth = overflowElement.current?.children[0].clientWidth || 0;
19
+ const scrollWidth = overflowElement.current?.scrollWidth || 0;
20
+ const scrollLeft = overflowElement.current?.scrollLeft || 0;
21
+ const overflowElementWidth = overflowElement.current?.offsetWidth || 0;
22
+ const overflowElementScrollWidth = scrollWidth - overflowElementWidth;
23
+ if (overflowElementScrollWidth !== scrollLeft) {
24
+ overflowElement.current?.scroll({
25
+ left: scrollLeft + itemWidth,
26
+ behavior: 'smooth',
27
+ });
28
+ }
29
+ }, []);
30
+ // Hide navigation buttons depending on scroll position
31
+ const [hidePrevNav, setHidePrevNav] = useState(true);
32
+ const [hideNextNav, setHideNextNav] = useState(true);
33
+ const onScroll = () => {
34
+ const scrollLeft = overflowElement.current?.scrollLeft || 0;
35
+ const scrollWidth = overflowElement.current?.scrollWidth || 0;
36
+ const overflowElementWidth = overflowElement.current?.offsetWidth || 0;
37
+ const overflowElementScrollWidth = scrollWidth - overflowElementWidth;
38
+ setHidePrevNav(scrollLeft == 0 ? true : false);
39
+ setHideNextNav(overflowElementScrollWidth == scrollLeft ? true : false);
40
+ };
41
+ useEffect(() => {
42
+ onScroll();
43
+ overflowElement.current?.addEventListener('scroll', onScroll);
44
+ return () => overflowElement.current?.removeEventListener('scroll', onScroll);
45
+ }, []);
46
+ return (React.createElement(Wrapper, { "$accentBg": accentBg },
47
+ React.createElement(ListWrapper, { "$spacing": spacing },
48
+ React.createElement(List, { ref: overflowElement, "$columns": columns, "$columnsSm": columnsSm, "$columnsMd": columnsMd }, items.map((item, i) => (React.createElement(Item, { key: itemKeyBase ? `${itemKeyBase}-${i}` : `overflow-grid-item-${i}` }, item))))),
49
+ !hidePrevNav && (React.createElement(PrevBtn, null,
50
+ React.createElement(NavButton, { onClick: onPrev, title: "Previous" },
51
+ React.createElement(IconChevronLeft, null)))),
52
+ !hideNextNav && (React.createElement(NextBtn, null,
53
+ React.createElement(NavButton, { onClick: onNext, title: "Next" },
54
+ React.createElement(IconChevronRight, null))))));
55
+ };
56
+ export default OverflowGrid;
@@ -0,0 +1,144 @@
1
+ import styled, { css } from 'styled-components';
2
+ import { size } from '../../layout/helpers';
3
+ export const Wrapper = styled.div `
4
+ --container-gutter: ${size(2)};
5
+ --bg: ${(props) => props.theme.color.bg};
6
+
7
+ ${(props) => props.theme.breakpoint.Sm} {
8
+ --container-gutter: ${size(3)};
9
+ }
10
+
11
+ position: relative;
12
+
13
+ ${({ $accentBg }) => $accentBg &&
14
+ css `
15
+ --bg: ${(props) => props.theme.color.accent};
16
+ `}
17
+ `;
18
+ export const Item = styled.li `
19
+ flex: 1 0 auto;
20
+ width: 100%;
21
+ max-width: 100%;
22
+ scroll-snap-align: start;
23
+
24
+ ${(props) => props.theme.breakpoint.LtSm} {
25
+ &:is(:only-child, #important) {
26
+ width: 100%;
27
+ max-width: 100%;
28
+ }
29
+ }
30
+ `;
31
+ export const List = styled.ul `
32
+ display: flex;
33
+ align-items: stretch;
34
+ list-style: none;
35
+ padding: 0 var(--container-gutter);
36
+ margin: 0;
37
+ overflow: auto;
38
+ scroll-snap-type: x mandatory;
39
+ scroll-padding-left: var(--container-gutter);
40
+ scrollbar-width: none;
41
+ -ms-overflow-style: none;
42
+
43
+ &::-webkit-scrollbar {
44
+ display: none;
45
+ }
46
+
47
+ ${({ $columns }) => $columns &&
48
+ css `
49
+ ${Item} {
50
+ width: ${100 / $columns}%;
51
+ max-width: ${100 / $columns}%;
52
+ }
53
+ `}
54
+
55
+ ${({ $columnsSm }) => $columnsSm &&
56
+ css `
57
+ ${(props) => props.theme.breakpoint.Sm} {
58
+ ${Item} {
59
+ width: ${100 / $columnsSm}%;
60
+ max-width: ${100 / $columnsSm}%;
61
+ }
62
+ }
63
+ `}
64
+
65
+ ${({ $columnsMd }) => $columnsMd &&
66
+ css `
67
+ ${(props) => props.theme.breakpoint.Md} {
68
+ ${Item} {
69
+ width: ${100 / $columnsMd}%;
70
+ max-width: ${100 / $columnsMd}%;
71
+ }
72
+ }
73
+ `}
74
+ `;
75
+ export const ListWrapper = styled.div `
76
+ position: relative;
77
+ overflow: hidden;
78
+ margin: 0 calc(var(--container-gutter) * -1);
79
+
80
+ ${(props) => props.theme.breakpoint.Md} {
81
+ &::before,
82
+ &::after {
83
+ content: '';
84
+ position: absolute;
85
+ top: 0;
86
+ bottom: 0;
87
+ width: var(--container-gutter);
88
+ background-color: var(--bg);
89
+ z-index: 1;
90
+ }
91
+
92
+ &::before {
93
+ left: 0;
94
+
95
+ ${({ $spacing }) => $spacing
96
+ ? css `
97
+ mask-image: linear-gradient(to right, #000 ${size($spacing)}, transparent);
98
+ `
99
+ : css `
100
+ mask-image: ${(props) => props.theme.mask.gradient.toRight};
101
+ `}
102
+ }
103
+
104
+ &::after {
105
+ right: 0;
106
+
107
+ ${({ $spacing }) => $spacing
108
+ ? css `
109
+ mask-image: linear-gradient(to left, #000 ${size($spacing)}, transparent);
110
+ `
111
+ : css `
112
+ mask-image: ${(props) => props.theme.mask.gradient.toLeft};
113
+ `}
114
+ }
115
+ }
116
+
117
+ ${({ $spacing }) => $spacing &&
118
+ css `
119
+ ${List} {
120
+ margin: 0 -${size($spacing / 2)};
121
+ }
122
+
123
+ ${Item} {
124
+ padding: 0 ${size($spacing / 2)};
125
+ }
126
+ `}
127
+ `;
128
+ const NavBtn = styled.div `
129
+ position: absolute;
130
+ top: 50%;
131
+ z-index: 2;
132
+
133
+ ${(props) => props.theme.breakpoint.LtSm} {
134
+ display: none;
135
+ }
136
+ `;
137
+ export const PrevBtn = styled(NavBtn) `
138
+ left: 0;
139
+ transform: translate(-50%, -50%);
140
+ `;
141
+ export const NextBtn = styled(NavBtn) `
142
+ right: 0;
143
+ transform: translate(50%, -50%);
144
+ `;
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ import { Wrapper, Row, Label, Price } from './wrapper';
3
+ const PriceBox = ({ prices }) => (React.createElement(Wrapper, null, prices?.map((item, i) => (React.createElement(Row, { key: `${item.label}-${i}`, "$oldPrice": item.oldPrice },
4
+ React.createElement(Label, null, item.label),
5
+ React.createElement(Price, null, item.price))))));
6
+ export default PriceBox;
@@ -0,0 +1,34 @@
1
+ import styled, { css } from 'styled-components';
2
+ import { size } from '../../layout/helpers';
3
+ export const Wrapper = styled.ul `
4
+ --price-box-gutter: ${size(2)};
5
+
6
+ list-style: none;
7
+ padding: var(--price-box-gutter);
8
+ margin: 0;
9
+ border: 1px solid ${(props) => props.theme.color.border};
10
+ `;
11
+ export const Row = styled.li `
12
+ display: flex;
13
+ align-items: center;
14
+ justify-content: space-between;
15
+ gap: var(--price-box-gutter);
16
+
17
+ & + & {
18
+ margin-top: calc(var(--price-box-gutter) / 4);
19
+ }
20
+
21
+ ${({ $oldPrice }) => $oldPrice &&
22
+ css `
23
+ --price-text-decoration: line-through;
24
+
25
+ color: ${(props) => props.theme.color.textDarkLighten};
26
+ font-size: 0.875rem;
27
+ `}
28
+ `;
29
+ export const Label = styled.div ``;
30
+ export const Price = styled.div.attrs(() => ({
31
+ className: 'wayke__theme wayke__font--bold',
32
+ })) `
33
+ text-decoration: var(--price-text-decoration);
34
+ `;