@treely/strapi-slices 5.3.0 → 5.3.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@treely/strapi-slices",
3
- "version": "5.3.0",
3
+ "version": "5.3.2",
4
4
  "license": "MIT",
5
5
  "author": "Tree.ly GmbH",
6
6
  "description": "@treely/strapi-slices is a open source library maintained by Tree.ly.",
@@ -1,4 +1,4 @@
1
- import React, { useRef, useState } from 'react';
1
+ import React, { useMemo, useRef, useState } from 'react';
2
2
  import {
3
3
  Box,
4
4
  IconButton,
@@ -16,7 +16,6 @@ import strapiMediaUrl from '../../utils/strapiMediaUrl';
16
16
  import FullScreenImage from '../../components/FullScreenImage';
17
17
  import { BREAKPOINT_MD_QUERY } from '../../constants/breakpoints';
18
18
  import {
19
- ButtonsContainer,
20
19
  ItemContainer,
21
20
  SliderContainer,
22
21
  SliderInnerContainer,
@@ -33,6 +32,10 @@ export interface FullWidthImageSliderProps {
33
32
  }[];
34
33
  };
35
34
  }
35
+
36
+ const ITEM_GAP = 24;
37
+ const MAX_OFFSET_RIGHT = 162;
38
+
36
39
  export const FullWidthImageSlider: React.FC<FullWidthImageSliderProps> = ({
37
40
  slice,
38
41
  }: FullWidthImageSliderProps) => {
@@ -44,9 +47,34 @@ export const FullWidthImageSlider: React.FC<FullWidthImageSliderProps> = ({
44
47
  const [sliderIndex, setSliderIndex] = useState(0);
45
48
  const [isOpen, setIsOpen] = useState(false);
46
49
 
47
- const allowScroll = windowWidth / 2 / imageWidth < slice.images.length;
48
- const canMoveRight = sliderIndex < slice.images.length - 1;
49
- const canMoveLeft = sliderIndex !== 0;
50
+ const numberOfItems = useMemo(
51
+ () => slice.images.length,
52
+ [slice.images.length]
53
+ );
54
+
55
+ const sliderItemsWidth = useMemo(
56
+ () => numberOfItems * (imageWidth + ITEM_GAP) - ITEM_GAP,
57
+ [imageWidth, numberOfItems]
58
+ );
59
+
60
+ const offsetLeft = useMemo(
61
+ () => sliderIndex * (imageWidth + ITEM_GAP) * -1,
62
+ [sliderIndex, imageWidth]
63
+ );
64
+
65
+ const allowScroll = useMemo(
66
+ () => sliderItemsWidth + ITEM_GAP * 3 > windowWidth,
67
+
68
+ [sliderItemsWidth, windowWidth]
69
+ );
70
+
71
+ const canMoveRight = useMemo(() => {
72
+ const offsetRight = windowWidth - (sliderItemsWidth + offsetLeft);
73
+
74
+ return offsetRight < MAX_OFFSET_RIGHT;
75
+ }, [imageWidth, sliderIndex, sliderItemsWidth, windowWidth]);
76
+
77
+ const canMoveLeft = useMemo(() => sliderIndex !== 0, [sliderIndex]);
50
78
 
51
79
  return (
52
80
  <DefaultSectionContainer>
@@ -97,7 +125,17 @@ export const FullWidthImageSlider: React.FC<FullWidthImageSliderProps> = ({
97
125
  </SliderInnerContainer>
98
126
  </SliderContainer>
99
127
 
100
- <ButtonsContainer show={(allowScroll && !isOpen).toString()}>
128
+ <Box
129
+ display={['none', null, null, !!allowScroll ? 'flex' : 'none']}
130
+ pointerEvents="none"
131
+ position="absolute"
132
+ top="calc(50% - var(--boemly-sizes-12))"
133
+ left="0"
134
+ width="full"
135
+ py="0"
136
+ px="32"
137
+ justifyContent="space-between"
138
+ >
101
139
  <Box>
102
140
  <AnimatePresence>
103
141
  {canMoveLeft && (
@@ -136,7 +174,7 @@ export const FullWidthImageSlider: React.FC<FullWidthImageSliderProps> = ({
136
174
  )}
137
175
  </AnimatePresence>
138
176
  </Box>
139
- </ButtonsContainer>
177
+ </Box>
140
178
 
141
179
  <FullScreenImage
142
180
  images={slice.images.map((image) => image.img)}
@@ -25,27 +25,6 @@ export const SliderContainer = styled(Box)`
25
25
  }
26
26
  `;
27
27
 
28
- interface ButtonsContainerProps {
29
- show: string;
30
- }
31
- export const ButtonsContainer = styled(Box)<ButtonsContainerProps>`
32
- display: ${({ show }: ButtonsContainerProps) => (show ? 'flex' : 'none')};
33
- pointer-events: none;
34
-
35
- // Place at 50% of height of tallest image minus size of button
36
- position: absolute;
37
- top: calc(50% - var(--boemly-sizes-12));
38
- left: 0;
39
- width: var(--boemly-sizes-full);
40
-
41
- padding: 0 var(--boemly-sizes-32);
42
- justify-content: space-between;
43
-
44
- @media screen and (max-width: ${BREAKPOINT_MD}) {
45
- display: none;
46
- }
47
- `;
48
-
49
28
  interface SliderInnerContainerProps {
50
29
  imageCount: number;
51
30
  }
@@ -1,4 +1,4 @@
1
- import React, { useContext, useRef, useState } from 'react';
1
+ import React, { useContext, useMemo, useRef, useState } from 'react';
2
2
  import {
3
3
  Box,
4
4
  Center,
@@ -33,22 +33,49 @@ export interface TextCarouselProps {
33
33
  slice: TextCarouselSlice;
34
34
  }
35
35
 
36
+ const ITEM_GAP = 24;
37
+ const MAX_OFFSET_RIGHT = 55;
38
+
36
39
  export const TextCarousel: React.FC<TextCarouselProps> = ({
37
40
  slice,
38
41
  }: TextCarouselProps) => {
42
+ const containerRef = useRef(null);
39
43
  const [primary50] = useToken('colors', ['primary.50']);
40
- const [slideRef, { width: slideWidth }] = useMeasure<HTMLDivElement>();
44
+ const [itemRef, { width: itemWidth }] = useMeasure<HTMLDivElement>();
41
45
  const { formatMessage } = useContext(IntlContext);
42
-
43
- const containerRef = useRef(null);
44
-
45
46
  const { width: windowWidth } = useWindowSize();
46
47
 
47
48
  const [sliderIndex, setSliderIndex] = useState(0);
48
49
 
49
- const allowScroll = windowWidth / 2 / slideWidth < slice.slides.length;
50
- const canMoveRight = sliderIndex < slice.slides.length - 1;
51
- const canMoveLeft = sliderIndex !== 0;
50
+ const numberOfItems = useMemo(
51
+ () => slice.slides.length,
52
+ [slice.slides.length]
53
+ );
54
+
55
+ const sliderItemsWidth = useMemo(
56
+ () => numberOfItems * (itemWidth + ITEM_GAP) - ITEM_GAP,
57
+ [itemWidth, numberOfItems]
58
+ );
59
+
60
+ const offsetLeft = useMemo(
61
+ () => sliderIndex * (itemWidth + ITEM_GAP) * -1,
62
+ [sliderIndex, itemWidth]
63
+ );
64
+
65
+ const allowScroll = useMemo(
66
+ () => sliderItemsWidth + ITEM_GAP * 2 > windowWidth,
67
+
68
+ [sliderItemsWidth, windowWidth]
69
+ );
70
+
71
+ const canMoveRight = useMemo(() => {
72
+ const offsetRight = windowWidth - (sliderItemsWidth + offsetLeft);
73
+
74
+ return offsetRight < MAX_OFFSET_RIGHT;
75
+ }, [itemWidth, sliderIndex, sliderItemsWidth, windowWidth]);
76
+
77
+ const canMoveLeft = useMemo(() => sliderIndex !== 0, [sliderIndex]);
78
+
52
79
  return (
53
80
  <DefaultSectionContainer backgroundColor={primary50} title={slice.title}>
54
81
  <Wrapper>
@@ -65,9 +92,9 @@ export const TextCarousel: React.FC<TextCarouselProps> = ({
65
92
  <CarouselContainer ref={containerRef}>
66
93
  <Box position="relative" width="full">
67
94
  <CarouselInnerContainer
68
- numberofitems={slice.slides.length}
95
+ numberOfItems={slice.slides.length}
69
96
  animate={{
70
- x: slideWidth * -sliderIndex,
97
+ x: offsetLeft,
71
98
  }}
72
99
  transition={{
73
100
  duration: 0.3,
@@ -75,11 +102,7 @@ export const TextCarousel: React.FC<TextCarouselProps> = ({
75
102
  }}
76
103
  >
77
104
  {slice.slides.map(({ id, title, text, icon }) => (
78
- <CardContainer
79
- key={id}
80
- ref={slideRef}
81
- numberofitems={slice.slides.length}
82
- >
105
+ <CardContainer key={id} ref={itemRef}>
83
106
  <TextCardWithIcon
84
107
  title={title}
85
108
  text={text}
@@ -9,10 +9,10 @@ export const CarouselContainer = styled(Box)`
9
9
 
10
10
  @media screen and (max-width: ${BREAKPOINT_MD}) {
11
11
  margin-top: var(--boemly-space-4);
12
- width: var(--boemly-size-full);
12
+ width: var(--boemly-sizes-full);
13
13
  }
14
14
 
15
- width: var(--boemly-size-full);
15
+ width: var(--boemly-sizes-full);
16
16
 
17
17
  overflow-x: hidden;
18
18
 
@@ -22,17 +22,19 @@ export const CarouselContainer = styled(Box)`
22
22
  `;
23
23
 
24
24
  interface CarouselInnerContainerProps {
25
- numberofitems: number;
25
+ numberOfItems: number;
26
26
  }
27
27
  export const CarouselInnerContainer = styled(
28
28
  motion.div
29
29
  )<CarouselInnerContainerProps>`
30
30
  display: flex;
31
+ gap: var(--boemly-space-6);
31
32
  justify-content: center;
33
+
32
34
  width: calc(
33
- (var(--boemly-sizes-sm) + var(--boemly-space-16)) *
34
- ${({ numberofitems }: CarouselInnerContainerProps) => numberofitems} +
35
- var(--boemly-space-16)
35
+ (var(--boemly-sizes-sm) + var(--boemly-space-6)) *
36
+ ${({ numberOfItems }: CarouselInnerContainerProps) => numberOfItems} +
37
+ var(--boemly-space-6)
36
38
  );
37
39
  min-width: var(--boemly-sizes-full);
38
40
 
@@ -40,24 +42,14 @@ export const CarouselInnerContainer = styled(
40
42
  justify-content: flex-start;
41
43
  width: calc(
42
44
  (var(--boemly-sizes-2xs) + var(--boemly-space-4)) *
43
- ${({ numberofitems }: CarouselInnerContainerProps) => numberofitems} +
45
+ ${({ numberOfItems }: CarouselInnerContainerProps) => numberOfItems} +
44
46
  var(--boemly-space-6)
45
47
  );
46
48
  }
47
49
  `;
48
50
 
49
- interface CardContainerProps {
50
- numberofitems: number;
51
- }
52
- export const CardContainer = styled(Box)<CardContainerProps>`
53
- width: ${({ numberofitems }: CardContainerProps) =>
54
- numberofitems === 3 ? 'var(--boemly-sizes-xl)' : 'var(--boemly-sizes-sm)'};
55
-
56
- margin-right: var(--boemly-space-6);
57
-
58
- &:first-of-type {
59
- margin-left: var(--boemly-space-6);
60
- }
51
+ export const CardContainer = styled(Box)`
52
+ width: var(--boemly-sizes-sm);
61
53
 
62
54
  @media screen and (max-width: ${BREAKPOINT_MD}) {
63
55
  width: var(--boemly-sizes-2xs);