@blaze-cms/react-page-builder 0.139.0-project-admin-customisations.0 → 0.139.1-core-styles.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 (252) hide show
  1. package/CHANGELOG.md +77 -3
  2. package/README.md +9 -0
  3. package/lib/components/Banner/BannerRender.js +2 -2
  4. package/lib/components/Banner/BannerRender.js.map +1 -1
  5. package/lib/components/Banner/helpers.js +2 -2
  6. package/lib/components/Banner/helpers.js.map +1 -1
  7. package/lib/components/BlazeLink.js +2 -2
  8. package/lib/components/BlazeLink.js.map +1 -1
  9. package/lib/components/Button.js +2 -2
  10. package/lib/components/Button.js.map +1 -1
  11. package/lib/components/Card/Card.js +5 -3
  12. package/lib/components/Card/Card.js.map +1 -1
  13. package/lib/components/Card/CardsContainer.js +3 -6
  14. package/lib/components/Card/CardsContainer.js.map +1 -1
  15. package/lib/components/Card/CardsRender.js +3 -4
  16. package/lib/components/Card/CardsRender.js.map +1 -1
  17. package/lib/components/Card/helpers/filter-query-setup.js +2 -2
  18. package/lib/components/Card/helpers/filter-query-setup.js.map +1 -1
  19. package/lib/components/Carousel/Carousel.js +26 -17
  20. package/lib/components/Carousel/Carousel.js.map +1 -1
  21. package/lib/components/Carousel/CarouselRender/CarouselRender.js +34 -60
  22. package/lib/components/Carousel/CarouselRender/CarouselRender.js.map +1 -1
  23. package/lib/components/Carousel/hooks/useCarouselNavigation.js +56 -0
  24. package/lib/components/Carousel/hooks/useCarouselNavigation.js.map +1 -0
  25. package/lib/components/ClickWrapper.js +2 -2
  26. package/lib/components/ClickWrapper.js.map +1 -1
  27. package/lib/components/Code/Code.js +2 -2
  28. package/lib/components/Code/Code.js.map +1 -1
  29. package/lib/components/Image/Image.js +2 -2
  30. package/lib/components/Image/Image.js.map +1 -1
  31. package/lib/components/Image/ImageFactory.js +20 -8
  32. package/lib/components/Image/ImageFactory.js.map +1 -1
  33. package/lib/components/Image/ImageRender.js +8 -2
  34. package/lib/components/Image/ImageRender.js.map +1 -1
  35. package/lib/components/Layout/Layout.js +9 -5
  36. package/lib/components/Layout/Layout.js.map +1 -1
  37. package/lib/components/List/ListBuilder.js +2 -2
  38. package/lib/components/List/ListBuilder.js.map +1 -1
  39. package/lib/components/List/ListFactory.js +2 -2
  40. package/lib/components/List/ListFactory.js.map +1 -1
  41. package/lib/components/List/components/Cards/CardsRender.js +2 -2
  42. package/lib/components/List/components/Cards/CardsRender.js.map +1 -1
  43. package/lib/components/List/components/Full/FullRender.js +9 -5
  44. package/lib/components/List/components/Full/FullRender.js.map +1 -1
  45. package/lib/components/List/components/Full/FullRenderItem.js +2 -2
  46. package/lib/components/List/components/Full/FullRenderItem.js.map +1 -1
  47. package/lib/components/List/components/Pagination/ListPagination.js +2 -2
  48. package/lib/components/List/components/Pagination/ListPagination.js.map +1 -1
  49. package/lib/components/List/helpers/build-az-url.js +2 -2
  50. package/lib/components/List/helpers/build-az-url.js.map +1 -1
  51. package/lib/components/List/helpers/build-pagination-url.js +2 -2
  52. package/lib/components/List/helpers/build-pagination-url.js.map +1 -1
  53. package/lib/components/SearchContent/SearchContent.js +55 -52
  54. package/lib/components/SearchContent/SearchContent.js.map +1 -1
  55. package/lib/components/SearchContent/SearchContentResults.js +16 -17
  56. package/lib/components/SearchContent/SearchContentResults.js.map +1 -1
  57. package/lib/components/SearchContent/SearchContentToggleIcon.js +8 -16
  58. package/lib/components/SearchContent/SearchContentToggleIcon.js.map +1 -1
  59. package/lib/components/SearchContent/constants.js +12 -0
  60. package/lib/components/SearchContent/constants.js.map +1 -0
  61. package/lib/components/SearchFilter/components/Range.js +2 -2
  62. package/lib/components/SearchFilter/components/Range.js.map +1 -1
  63. package/lib/components/SearchFilter/searchFilterReducer.js +2 -2
  64. package/lib/components/SearchFilterSort/helpers/update-sort.js +2 -2
  65. package/lib/components/SearchFilterSort/helpers/update-sort.js.map +1 -1
  66. package/lib/components/TextBlock/index.js +2 -2
  67. package/lib/components/TextBlock/index.js.map +1 -1
  68. package/lib/components/Video/Video.js +2 -2
  69. package/lib/components/Video/Video.js.map +1 -1
  70. package/lib/components/Video/providers/JWPlayer/JWPlayerProvider.js +2 -2
  71. package/lib/components/Video/providers/JWPlayer/JWPlayerProvider.js.map +1 -1
  72. package/lib/helpers/append-images.js +2 -2
  73. package/lib/helpers/build-raw-query-base.js +2 -2
  74. package/lib/helpers/build-raw-query-base.js.map +1 -1
  75. package/lib/helpers/build-raw-query.js +2 -2
  76. package/lib/helpers/build-raw-query.js.map +1 -1
  77. package/lib/helpers/get-banner-data.js +2 -2
  78. package/lib/helpers/get-click-wrapper-options.js +2 -2
  79. package/lib/helpers/get-click-wrapper-options.js.map +1 -1
  80. package/lib/helpers/get-entities-with-banner.js +2 -2
  81. package/lib/helpers/get-entities-with-banner.js.map +1 -1
  82. package/lib/helpers/get-generic-props.js +2 -2
  83. package/lib/helpers/get-generic-props.js.map +1 -1
  84. package/lib/helpers/get-generic-render-variables.js +2 -2
  85. package/lib/helpers/get-generic-render-variables.js.map +1 -1
  86. package/lib/helpers/inject-multiple-banners/get-banners-for-nodes/get-banners-for-nodes.js +2 -2
  87. package/lib/helpers/inject-multiple-banners/get-banners-for-nodes/get-banners-for-nodes.js.map +1 -1
  88. package/lib/helpers/process-data-summary-value.js +2 -2
  89. package/lib/helpers/process-data-summary-value.js.map +1 -1
  90. package/lib/helpers/remove-unwanted-characters.js +2 -2
  91. package/lib/helpers/render-children.js +2 -2
  92. package/lib/helpers/render-children.js.map +1 -1
  93. package/lib/helpers/split-children.js +2 -2
  94. package/lib/helpers/update-childrens-parent.js +2 -2
  95. package/lib/hooks/helpers/RenderComponent.js +9 -2
  96. package/lib/hooks/helpers/RenderComponent.js.map +1 -1
  97. package/lib/hooks/helpers/append-gtm-classname.js +2 -2
  98. package/lib/hooks/helpers/append-gtm-classname.js.map +1 -1
  99. package/lib/hooks/helpers/buildPBComponents.js +2 -2
  100. package/lib/hooks/helpers/buildPBComponents.js.map +1 -1
  101. package/lib/hooks/helpers/get-lightbox-images.js +2 -2
  102. package/lib/hooks/helpers/get-lightbox-images.js.map +1 -1
  103. package/lib/hooks/helpers/getVariant.js +18 -0
  104. package/lib/hooks/helpers/getVariant.js.map +1 -0
  105. package/lib/hooks/helpers/inject-element-banners.js +2 -2
  106. package/lib/hooks/helpers/inject-element-banners.js.map +1 -1
  107. package/lib/hooks/helpers/inject-textblock-banners.js +2 -2
  108. package/lib/hooks/helpers/inject-textblock-banners.js.map +1 -1
  109. package/lib/hooks/use-get-image-id-from-relation.js +2 -2
  110. package/lib/hooks/use-get-image-id-from-relation.js.map +1 -1
  111. package/lib/hooks/use-get-images.js +4 -3
  112. package/lib/hooks/use-get-images.js.map +1 -1
  113. package/lib/index.js +13 -0
  114. package/lib/index.js.map +1 -1
  115. package/lib/utils/component-map.js +4 -4
  116. package/lib/utils/component-map.js.map +1 -1
  117. package/lib/utils/get-class-modifiers.js +2 -2
  118. package/lib/utils/get-class-modifiers.js.map +1 -1
  119. package/lib/utils/index.js +7 -0
  120. package/lib/utils/index.js.map +1 -1
  121. package/lib/utils/variant-handler.js +40 -0
  122. package/lib/utils/variant-handler.js.map +1 -0
  123. package/lib/variants/index.js +10 -0
  124. package/lib/variants/index.js.map +1 -0
  125. package/lib-es/components/Banner/BannerRender.js +2 -2
  126. package/lib-es/components/Banner/helpers.js +2 -2
  127. package/lib-es/components/BlazeLink.js +2 -2
  128. package/lib-es/components/Button.js +2 -2
  129. package/lib-es/components/Card/Card.js +5 -3
  130. package/lib-es/components/Card/Card.js.map +1 -1
  131. package/lib-es/components/Card/CardsContainer.js +4 -7
  132. package/lib-es/components/Card/CardsContainer.js.map +1 -1
  133. package/lib-es/components/Card/CardsRender.js +3 -4
  134. package/lib-es/components/Card/CardsRender.js.map +1 -1
  135. package/lib-es/components/Card/helpers/filter-query-setup.js +2 -2
  136. package/lib-es/components/Carousel/Carousel.js +27 -17
  137. package/lib-es/components/Carousel/Carousel.js.map +1 -1
  138. package/lib-es/components/Carousel/CarouselRender/CarouselRender.js +33 -53
  139. package/lib-es/components/Carousel/CarouselRender/CarouselRender.js.map +1 -1
  140. package/lib-es/components/Carousel/hooks/useCarouselNavigation.js +49 -0
  141. package/lib-es/components/Carousel/hooks/useCarouselNavigation.js.map +1 -0
  142. package/lib-es/components/ClickWrapper.js +2 -2
  143. package/lib-es/components/Code/Code.js +2 -2
  144. package/lib-es/components/Image/Image.js +2 -2
  145. package/lib-es/components/Image/ImageFactory.js +18 -8
  146. package/lib-es/components/Image/ImageFactory.js.map +1 -1
  147. package/lib-es/components/Image/ImageRender.js +9 -3
  148. package/lib-es/components/Image/ImageRender.js.map +1 -1
  149. package/lib-es/components/Layout/Layout.js +10 -6
  150. package/lib-es/components/Layout/Layout.js.map +1 -1
  151. package/lib-es/components/List/ListBuilder.js +2 -2
  152. package/lib-es/components/List/ListFactory.js +2 -2
  153. package/lib-es/components/List/components/Cards/CardsRender.js +2 -2
  154. package/lib-es/components/List/components/Full/FullRender.js +11 -7
  155. package/lib-es/components/List/components/Full/FullRender.js.map +1 -1
  156. package/lib-es/components/List/components/Full/FullRenderItem.js +2 -2
  157. package/lib-es/components/List/components/Pagination/ListPagination.js +2 -2
  158. package/lib-es/components/List/helpers/build-az-url.js +2 -2
  159. package/lib-es/components/List/helpers/build-pagination-url.js +2 -2
  160. package/lib-es/components/SearchContent/SearchContent.js +53 -49
  161. package/lib-es/components/SearchContent/SearchContent.js.map +1 -1
  162. package/lib-es/components/SearchContent/SearchContentResults.js +16 -17
  163. package/lib-es/components/SearchContent/SearchContentResults.js.map +1 -1
  164. package/lib-es/components/SearchContent/SearchContentToggleIcon.js +13 -23
  165. package/lib-es/components/SearchContent/SearchContentToggleIcon.js.map +1 -1
  166. package/lib-es/components/SearchContent/constants.js +4 -0
  167. package/lib-es/components/SearchContent/constants.js.map +1 -0
  168. package/lib-es/components/SearchFilter/components/Range.js +2 -2
  169. package/lib-es/components/SearchFilter/searchFilterReducer.js +2 -2
  170. package/lib-es/components/SearchFilterSort/helpers/update-sort.js +2 -2
  171. package/lib-es/components/TextBlock/index.js +2 -2
  172. package/lib-es/components/Video/Video.js +2 -2
  173. package/lib-es/components/Video/providers/JWPlayer/JWPlayerProvider.js +2 -2
  174. package/lib-es/helpers/append-images.js +2 -2
  175. package/lib-es/helpers/build-raw-query-base.js +2 -2
  176. package/lib-es/helpers/build-raw-query.js +2 -2
  177. package/lib-es/helpers/get-banner-data.js +2 -2
  178. package/lib-es/helpers/get-click-wrapper-options.js +2 -2
  179. package/lib-es/helpers/get-entities-with-banner.js +2 -2
  180. package/lib-es/helpers/get-generic-props.js +2 -2
  181. package/lib-es/helpers/get-generic-render-variables.js +2 -2
  182. package/lib-es/helpers/inject-multiple-banners/get-banners-for-nodes/get-banners-for-nodes.js +2 -2
  183. package/lib-es/helpers/process-data-summary-value.js +2 -2
  184. package/lib-es/helpers/remove-unwanted-characters.js +2 -2
  185. package/lib-es/helpers/render-children.js +2 -2
  186. package/lib-es/helpers/split-children.js +2 -2
  187. package/lib-es/helpers/update-childrens-parent.js +2 -2
  188. package/lib-es/hooks/helpers/RenderComponent.js +5 -2
  189. package/lib-es/hooks/helpers/RenderComponent.js.map +1 -1
  190. package/lib-es/hooks/helpers/append-gtm-classname.js +2 -2
  191. package/lib-es/hooks/helpers/buildPBComponents.js +2 -2
  192. package/lib-es/hooks/helpers/get-lightbox-images.js +2 -2
  193. package/lib-es/hooks/helpers/getVariant.js +14 -0
  194. package/lib-es/hooks/helpers/getVariant.js.map +1 -0
  195. package/lib-es/hooks/helpers/inject-element-banners.js +2 -2
  196. package/lib-es/hooks/helpers/inject-textblock-banners.js +2 -2
  197. package/lib-es/hooks/use-get-image-id-from-relation.js +2 -2
  198. package/lib-es/hooks/use-get-image-id-from-relation.js.map +1 -1
  199. package/lib-es/hooks/use-get-images.js +4 -4
  200. package/lib-es/hooks/use-get-images.js.map +1 -1
  201. package/lib-es/index.js +2 -1
  202. package/lib-es/index.js.map +1 -1
  203. package/lib-es/utils/component-map.js +4 -4
  204. package/lib-es/utils/component-map.js.map +1 -1
  205. package/lib-es/utils/get-class-modifiers.js +2 -2
  206. package/lib-es/utils/index.js +2 -1
  207. package/lib-es/utils/index.js.map +1 -1
  208. package/lib-es/utils/variant-handler.js +26 -0
  209. package/lib-es/utils/variant-handler.js.map +1 -0
  210. package/lib-es/variants/index.js +2 -0
  211. package/lib-es/variants/index.js.map +1 -0
  212. package/package.json +11 -11
  213. package/src/components/Card/Card.js +1 -2
  214. package/src/components/Card/CardsContainer.js +0 -3
  215. package/src/components/Card/CardsRender.js +0 -1
  216. package/src/components/Carousel/Carousel.js +28 -12
  217. package/src/components/Carousel/CarouselRender/CarouselRender.js +36 -56
  218. package/src/components/Carousel/hooks/useCarouselNavigation.js +50 -0
  219. package/src/components/Image/ImageFactory.js +20 -5
  220. package/src/components/Image/ImageRender.js +14 -8
  221. package/src/components/Layout/Layout.js +8 -5
  222. package/src/components/List/components/Full/FullRender.js +11 -3
  223. package/src/components/SearchContent/SearchContent.js +66 -52
  224. package/src/components/SearchContent/SearchContentResults.js +17 -17
  225. package/src/components/SearchContent/SearchContentToggleIcon.js +10 -23
  226. package/src/components/SearchContent/constants.js +6 -0
  227. package/src/hooks/helpers/RenderComponent.js +4 -0
  228. package/src/hooks/helpers/getVariant.js +11 -0
  229. package/src/hooks/use-get-image-id-from-relation.js +13 -2
  230. package/src/hooks/use-get-images.js +4 -4
  231. package/src/index.js +2 -1
  232. package/src/utils/component-map.js +4 -5
  233. package/src/utils/index.js +9 -1
  234. package/src/utils/variant-handler.js +33 -0
  235. package/src/variants/index.js +1 -0
  236. package/tests/unit/src/components/Carousel/Carousel.test.js +23 -0
  237. package/tests/unit/src/components/Carousel/CarouselRender/CarouselRender.test.js +14 -22
  238. package/tests/unit/src/components/Carousel/__snapshots__/Carousel.test.js.snap +10 -0
  239. package/tests/unit/src/components/Image/ImageFactory.test.js +20 -3
  240. package/tests/unit/src/components/Image/ImageRender.test.js +12 -0
  241. package/tests/unit/src/components/Image/__snapshots__/ImageFactory.test.js.snap +24 -0
  242. package/tests/unit/src/components/Image/__snapshots__/ImageRender.test.js.snap +9 -0
  243. package/tests/unit/src/components/Image/mocks.js +49 -1
  244. package/tests/unit/src/components/Layout/Layout.test.js +11 -0
  245. package/tests/unit/src/components/List/components/Full/FullRender.test.js +14 -1
  246. package/tests/unit/src/components/List/components/Full/__snapshots__/FullRender.test.js.snap +24 -6
  247. package/tests/unit/src/components/List/components/mocks.js +9 -3
  248. package/tests/unit/src/components/Menu/__snapshots__/Menu.test.js.snap +1 -1
  249. package/tests/unit/src/components/PlaceholderIcon/__snapshots__/index.test.js.snap +4 -6
  250. package/tests/unit/src/components/SearchContent/SearchContent.test.js +32 -7
  251. package/tests/unit/src/components/SearchContent/__snapshots__/SearchContent.test.js.snap +66 -2
  252. package/tests/unit/src/utils/variant-handler.test.js +41 -0
@@ -1,61 +1,26 @@
1
- import React, { useRef, useState } from 'react';
1
+ import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import CarouselImage from '../CarouselImage';
4
4
  import { withTitle } from '../../../HOC';
5
- import { getDisplayCountData } from '../../../helpers';
6
5
 
7
- const CarouselRender = ({ imageIds, displayCount, priorityLimit, ...otherProps }) => {
8
- const [showCount, setShowCount] = useState(displayCount);
9
- const listRef = useRef(null);
10
-
11
- const getListElement = () => {
12
- if (!listRef) return null;
13
- const { current } = listRef;
14
- return current;
15
- };
16
-
17
- const moveScroll = (numberOfPixels, isNext) => {
18
- const listElement = getListElement();
19
- if (!listElement) return;
20
-
21
- const totalDistance = listElement.scrollLeft + numberOfPixels;
22
- const { scrollLeft, offsetWidth, scrollWidth } = listElement;
23
- if (isNext && offsetWidth + scrollLeft >= scrollWidth) return;
24
-
25
- const leftPosition = totalDistance < 0 ? 0 : Math.max(-scrollLeft, totalDistance);
26
-
27
- listElement.scrollTo({
28
- top: 0,
29
- left: leftPosition,
30
- behavior: 'smooth'
31
- });
32
- };
33
-
34
- const handleNavigation = direction => {
35
- setShowCount(false);
36
-
37
- const listElement = getListElement();
38
- if (!listElement) return;
39
-
40
- const { scrollWidth } = listElement;
41
- const offset = scrollWidth / imageIds.length;
42
-
43
- direction ? moveScroll(offset, direction) : moveScroll(-offset, direction);
44
- };
45
-
46
- const navigation = {
47
- next: true,
48
- back: false
49
- };
50
-
51
- const { shouldDisplayCount, countMessage } = getDisplayCountData(showCount, imageIds);
52
-
53
- return (
54
- <>
6
+ const CarouselRender = ({
7
+ handleNavigation,
8
+ imageIds,
9
+ listRef,
10
+ shouldDisplayCount,
11
+ shouldDisplayCaption,
12
+ caption,
13
+ countMessage,
14
+ direction,
15
+ priorityLimit,
16
+ ...otherProps
17
+ }) => (
18
+ <div className="carousel">
19
+ <div>
55
20
  <div
56
21
  className="carousel__button carousel__button--previous"
57
22
  role="button"
58
- onClick={() => handleNavigation(navigation.back)}>
23
+ onClick={() => handleNavigation(direction.back)}>
59
24
  <div className="arrow arrow--left" />
60
25
  </div>
61
26
  <div className="carousel__list" ref={listRef}>
@@ -71,23 +36,38 @@ const CarouselRender = ({ imageIds, displayCount, priorityLimit, ...otherProps }
71
36
  <div
72
37
  className="carousel__button carousel__button--next"
73
38
  role="button"
74
- onClick={() => handleNavigation(navigation.next)}>
75
- {shouldDisplayCount && <p>{countMessage}</p>}
39
+ onClick={() => handleNavigation(direction.next)}>
40
+ {shouldDisplayCount && <p data-testid="count">{countMessage}</p>}
76
41
  <div className="arrow arrow--right" />
77
42
  </div>
78
- </>
79
- );
80
- };
43
+ </div>
44
+ {shouldDisplayCaption && (
45
+ <div className="carousel__details" data-testid="carousel-details">
46
+ <div className="caption">{caption}</div>
47
+ </div>
48
+ )}
49
+ </div>
50
+ );
81
51
 
82
52
  CarouselRender.propTypes = {
53
+ caption: PropTypes.string,
54
+ shouldDisplayCaption: PropTypes.bool.isRequired,
83
55
  imageIds: PropTypes.array,
84
56
  displayCount: PropTypes.bool,
57
+ listRef: PropTypes.object,
58
+ countMessage: PropTypes.number,
59
+ direction: PropTypes.object.isRequired,
60
+ handleNavigation: PropTypes.func.isRequired,
61
+ shouldDisplayCount: PropTypes.bool.isRequired,
85
62
  priorityLimit: PropTypes.number
86
63
  };
87
64
 
88
65
  CarouselRender.defaultProps = {
66
+ listRef: null,
89
67
  imageIds: [],
68
+ caption: '',
90
69
  displayCount: false,
70
+ countMessage: null,
91
71
  priorityLimit: 0
92
72
  };
93
73
 
@@ -0,0 +1,50 @@
1
+ import { useState, useRef } from 'react';
2
+
3
+ export function useCarouselNavigation({ imageIds, displayCount }) {
4
+ const [showCount, setShowCount] = useState(displayCount);
5
+ const listRef = useRef(null);
6
+
7
+ const getListElement = () => {
8
+ if (!listRef.current) return null;
9
+ return listRef.current;
10
+ };
11
+
12
+ const moveScroll = (numberOfPixels, isNext) => {
13
+ const listElement = getListElement();
14
+ if (!listElement) return;
15
+
16
+ const totalDistance = listElement.scrollLeft + numberOfPixels;
17
+ const { scrollLeft, offsetWidth, scrollWidth } = listElement;
18
+ if (isNext && offsetWidth + scrollLeft >= scrollWidth) return;
19
+
20
+ const leftPosition = totalDistance < 0 ? 0 : Math.max(-scrollLeft, totalDistance);
21
+
22
+ listElement.scrollTo({
23
+ top: 0,
24
+ left: leftPosition,
25
+ behavior: 'smooth'
26
+ });
27
+ };
28
+
29
+ const handleNavigation = direction => {
30
+ setShowCount(false);
31
+
32
+ const listElement = getListElement();
33
+ if (!listElement) return;
34
+
35
+ const { scrollWidth } = listElement;
36
+ const offset = scrollWidth / imageIds.length;
37
+
38
+ direction ? moveScroll(offset, direction) : moveScroll(-offset, direction);
39
+ };
40
+
41
+ return {
42
+ listRef,
43
+ showCount,
44
+ handleNavigation,
45
+ direction: {
46
+ next: true,
47
+ back: false
48
+ }
49
+ };
50
+ }
@@ -1,6 +1,7 @@
1
1
  import React, { useContext } from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import { MainContext } from '@blaze-cms/nextjs-components';
4
+ import { useStringTemplate } from '@blaze-cms/utils-handlebars';
4
5
  import Image from './Image';
5
6
  import { useGetImageIdFromRelation, useGetImages, useGetSingleEntitySchema } from '../../hooks';
6
7
  import { getImageIds, isUsingRelationImage as checkIfUsingRelationImage } from '../../helpers';
@@ -9,20 +10,30 @@ const ImageFactory = props => {
9
10
  const {
10
11
  imageId,
11
12
  parent: { itemId },
13
+ parent,
12
14
  entity,
13
15
  fetchFromRelation,
14
- imageRelation
16
+ imageRelation,
17
+ imgSrc
15
18
  } = props;
16
19
  const { isPreview } = useContext(MainContext);
20
+ const {
21
+ data: [imgSrcToUse]
22
+ } = useStringTemplate(parent, [imgSrc]);
23
+
24
+ const skipSingleEntitySchema = !entity || !!imgSrcToUse;
17
25
  const isUsingRelationImage = checkIfUsingRelationImage(entity, fetchFromRelation, imageRelation);
18
- const { data: { getEntitySchema = {} } = {} } = useGetSingleEntitySchema(entity, !entity);
19
- const { actions = {} } = getEntitySchema;
26
+ const { data: { getEntitySchema: { actions = {} } = {} } = {} } = useGetSingleEntitySchema(
27
+ entity,
28
+ skipSingleEntitySchema
29
+ );
20
30
  const { data: relationData, loading: relationLoading } = useGetImageIdFromRelation(
21
31
  itemId,
22
32
  imageRelation,
23
33
  actions,
24
34
  isUsingRelationImage,
25
- isPreview
35
+ isPreview,
36
+ !!imgSrcToUse
26
37
  );
27
38
 
28
39
  const updatedImageIds = relationLoading
@@ -32,12 +43,16 @@ const ImageFactory = props => {
32
43
  updatedImageIds && updatedImageIds.length === 1 ? updatedImageIds[0] : updatedImageIds;
33
44
  const { data: { getFile, getFiles = [] } = {}, loading, error } = useGetImages(
34
45
  imageIds,
35
- updatedImageIds && updatedImageIds.length > 1
46
+ updatedImageIds && updatedImageIds.length > 1,
47
+ !!imgSrcToUse
36
48
  );
37
49
  if (error) return error.message;
38
50
  if (loading) return '';
39
51
 
52
+ if (imgSrcToUse) return <Image {...props} imageUrl={imgSrcToUse} shouldRenderImgTag />;
53
+
40
54
  const files = getFile ? [getFile] : getFiles;
55
+
41
56
  return files.map(({ id, data: imageData = {}, url: imageUrl = '' }) => {
42
57
  if (!imageUrl) return null;
43
58
  return <Image key={id} {...props} imageData={imageData} imageUrl={imageUrl} />;
@@ -20,6 +20,7 @@ const ImageRender = ({
20
20
  isHero,
21
21
  priority,
22
22
  sizeKey,
23
+ shouldRenderImgTag,
23
24
  ...otherProps
24
25
  }) => {
25
26
  const imageStyle = enableLightbox ? { cursor: 'pointer' } : style;
@@ -27,14 +28,19 @@ const ImageRender = ({
27
28
 
28
29
  return (
29
30
  <>
30
- <ResponsiveImage
31
- sizeKey={sizeKey}
32
- alt={alt}
33
- src={imageUrl}
34
- onClick={handleEnableLightbox}
35
- style={imageStyle}
36
- HeadComponent={HeadComponent}
37
- />
31
+ {shouldRenderImgTag ? (
32
+ <img style={imageStyle} src={imageUrl} alt={alt} onClick={handleEnableLightbox} />
33
+ ) : (
34
+ <ResponsiveImage
35
+ sizeKey={sizeKey}
36
+ alt={alt}
37
+ src={imageUrl}
38
+ onClick={handleEnableLightbox}
39
+ style={imageStyle}
40
+ HeadComponent={HeadComponent}
41
+ />
42
+ )}
43
+
38
44
  {displayLightbox && (
39
45
  <Lightbox
40
46
  imageUrl={imageUrl}
@@ -18,6 +18,7 @@ const Layout = React.forwardRef(
18
18
  tagType,
19
19
  dataNoSnippet,
20
20
  sticky,
21
+ VariantComponent,
21
22
  ...otherProps
22
23
  },
23
24
  ref
@@ -25,10 +26,8 @@ const Layout = React.forwardRef(
25
26
  const {
26
27
  data: { getFile: { url = null } = {} }
27
28
  } = useGetImages(backgroundImage);
28
-
29
29
  const style = getStylesToUpdate({ backgroundImage: url });
30
30
  const { title } = settings;
31
-
32
31
  const classModifiers = getClassModifiers(type, { modifier, sticky, ...otherProps });
33
32
  const additionalRowModifier = checkIfRowHasColumns(type, children) ? ' display-row' : '';
34
33
 
@@ -37,8 +36,10 @@ const Layout = React.forwardRef(
37
36
  const otherWrapperProps = {};
38
37
  if (dataNoSnippet) otherWrapperProps['data-nosnippet'] = true;
39
38
 
39
+ const WrapperComponent = VariantComponent || Wrapper;
40
+
40
41
  return (
41
- <Wrapper
42
+ <WrapperComponent
42
43
  ref={ref}
43
44
  tagType={tagType}
44
45
  className={type}
@@ -47,7 +48,7 @@ const Layout = React.forwardRef(
47
48
  {...otherWrapperProps}>
48
49
  {title && <h2 className="heading heading--section">{title}</h2>}
49
50
  {renderChildren(children, otherProps)}
50
- </Wrapper>
51
+ </WrapperComponent>
51
52
  );
52
53
  }
53
54
  );
@@ -62,6 +63,7 @@ Layout.propTypes = {
62
63
  backgroundImage: PropTypes.string,
63
64
  tagType: PropTypes.string,
64
65
  dataNoSnippet: PropTypes.bool,
66
+ VariantComponent: PropTypes.func,
65
67
  children: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]).isRequired
66
68
  };
67
69
 
@@ -73,7 +75,8 @@ Layout.defaultProps = {
73
75
  modifier: '',
74
76
  tagType: '',
75
77
  dataNoSnippet: false,
76
- sticky: false
78
+ sticky: false,
79
+ VariantComponent: null
77
80
  };
78
81
 
79
82
  export default Layout;
@@ -9,7 +9,13 @@ import { BANNER } from '../../constants';
9
9
  import Wrapper from '../../../Wrapper';
10
10
  import { checkIfShouldRenderBanner } from '../helpers';
11
11
 
12
- const FullRender = ({ orderedListData, omitWrappers, paginationType, ...props }) => {
12
+ const FullRender = ({
13
+ orderedListData,
14
+ omitWrappers,
15
+ paginationType,
16
+ graphqlEntityMap,
17
+ ...props
18
+ }) => {
13
19
  const contextProps = useContext(MainContext);
14
20
  const pageBuilderID = uuid();
15
21
  const { parent, entity, propsToDisplay, banner, hasBanner } = props;
@@ -22,7 +28,7 @@ const FullRender = ({ orderedListData, omitWrappers, paginationType, ...props })
22
28
  return (
23
29
  <MainContextProvider value={{ ...contextProps, isPreview: false }}>
24
30
  <WrapperToUse className="list list--full">
25
- {orderedListData.map(({ id, ...entityProps }, i) => {
31
+ {orderedListData.map(({ id, __typename: dataEntity, ...entityProps }, i) => {
26
32
  const shouldRenderBanner = !!bannerProps && checkIfShouldRenderBanner(i, bannerProps);
27
33
  if (shouldRenderBanner) bannerIndex += 1;
28
34
 
@@ -31,6 +37,7 @@ const FullRender = ({ orderedListData, omitWrappers, paginationType, ...props })
31
37
  key={id}
32
38
  {...props}
33
39
  {...entityProps}
40
+ entity={graphqlEntityMap[dataEntity]}
34
41
  index={i}
35
42
  itemId={id}
36
43
  pageBuilderID={pageBuilderID}
@@ -58,7 +65,8 @@ FullRender.propTypes = {
58
65
  entity: PropTypes.string.isRequired,
59
66
  omitWrappers: PropTypes.bool,
60
67
  hasBanner: PropTypes.bool,
61
- banner: PropTypes.object
68
+ banner: PropTypes.object,
69
+ graphqlEntityMap: PropTypes.object.isRequired
62
70
  };
63
71
 
64
72
  FullRender.defaultProps = {
@@ -1,4 +1,4 @@
1
- import React, { useState, useEffect } from 'react';
1
+ import React, { useState, useEffect, useRef } from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import { useRouter } from 'next/router';
4
4
  import { useDebounceSearch } from '@blaze-cms/plugin-search-ui';
@@ -7,7 +7,6 @@ import SearchContentToggleIcon from './SearchContentToggleIcon';
7
7
 
8
8
  const SearchContent = ({
9
9
  entities,
10
- searchInputAlignment,
11
10
  searchInputWrapperMobile,
12
11
  searchInputWrapperDesktop,
13
12
  isMobile,
@@ -15,7 +14,9 @@ const SearchContent = ({
15
14
  modifier,
16
15
  collapsedSearch
17
16
  }) => {
17
+ const searchContentRef = useRef(null);
18
18
  const [collapsed, setCollapsed] = useState(collapsedSearch);
19
+ const [showResults, setShowResults] = useState(false);
19
20
  const router = useRouter();
20
21
 
21
22
  const { results, searchTerm, setSearchTerm, debouncedSearchTerm } = useDebounceSearch({
@@ -26,19 +27,44 @@ const SearchContent = ({
26
27
 
27
28
  useEffect(
28
29
  () => {
29
- const handleRouteChange = () => setSearchTerm('');
30
+ const handleRouteChange = () => {
31
+ setSearchTerm('');
32
+ setShowResults(false);
33
+ if (collapsedSearch) setCollapsed(true);
34
+ };
30
35
  router.events.on('routeChangeStart', handleRouteChange);
31
36
 
32
37
  return () => {
33
38
  router.events.off('routeChangeStart', handleRouteChange);
34
39
  };
35
40
  },
36
- [router.events, setSearchTerm]
41
+ [collapsedSearch, router.events, setSearchTerm]
42
+ );
43
+
44
+ useEffect(
45
+ () => {
46
+ const handleClickOutside = event => {
47
+ if (searchContentRef.current && !searchContentRef.current.contains(event.target)) {
48
+ setShowResults(false);
49
+ if (collapsedSearch) {
50
+ setCollapsed(true);
51
+ setSearchTerm('');
52
+ }
53
+ }
54
+ };
55
+
56
+ document.addEventListener('click', handleClickOutside);
57
+
58
+ return () => {
59
+ document.removeEventListener('click', handleClickOutside);
60
+ };
61
+ },
62
+ [collapsedSearch, setSearchTerm]
37
63
  );
38
64
 
39
65
  const responsiveClasses = isMobile ? searchInputWrapperMobile : searchInputWrapperDesktop;
40
66
 
41
- const handleClick = (e, url) => {
67
+ const handleNavigation = (e, url) => {
42
68
  e.preventDefault();
43
69
  router.push(url);
44
70
  };
@@ -49,71 +75,60 @@ const SearchContent = ({
49
75
  }
50
76
  };
51
77
 
52
- const handleOnBlur = () => {
53
- if (!collapsedSearch) return;
54
- if (!debouncedSearchTerm || debouncedSearchTerm === '') setCollapsed(true);
55
- };
78
+ const handleIconClick = () => {
79
+ const isCloseIcon = collapsedSearch ? !collapsed : debouncedSearchTerm;
80
+
81
+ if (collapsedSearch) setCollapsed(!collapsed);
56
82
 
57
- const handleClearSearchResults = () => {
58
- setSearchTerm('');
83
+ if (isCloseIcon) {
84
+ setSearchTerm('');
85
+ setShowResults(false);
86
+ } else {
87
+ setShowResults(true);
88
+ }
59
89
  };
60
90
 
61
91
  const className = ['search-content', modifier, responsiveClasses].filter(Boolean).join(' ');
62
- return collapsed ? (
63
- <div className={className}>
64
- <div className="search-content--collapse__wrapper">
65
- <label className="search-content--collapse__label">
66
- <span className="search-content--collapse__icon_wrapper">
67
- <svg className="search-content--collapse__icon" viewBox="0 0 20 20">
68
- <path
69
- fillRule="evenodd"
70
- d="M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z"
71
- clipRule="evenodd"
72
- />
73
- </svg>
92
+ const searchModifier = collapsed ? 'search-content--collapse' : 'search-content--expanded';
93
+
94
+ return (
95
+ <div className={className} ref={searchContentRef}>
96
+ <div className={`${searchModifier}__wrapper`}>
97
+ <label className={`${searchModifier}__label`}>
98
+ <span className={`${searchModifier}__icon_wrapper`}>
99
+ <SearchContentToggleIcon
100
+ searchTerm={debouncedSearchTerm}
101
+ onClick={handleIconClick}
102
+ useCloseIcon={collapsedSearch ? !collapsed : debouncedSearchTerm}
103
+ />
74
104
  </span>
75
- <input
76
- onFocus={() => setCollapsed(false)}
77
- onChange={e => setSearchTerm(e.target.value)}
78
- type="text"
79
- name="search"
80
- className="search-content--collapse__input"
81
- />
82
- </label>
83
- </div>
84
- </div>
85
- ) : (
86
- <>
87
- <div className={className}>
88
- <div className="search-content--expanded__wrapper">
89
- <label className="search-content--expanded__label">
90
- <span className="search-content--expanded__icon_wrapper">
91
- <SearchContentToggleIcon results={results} onClear={handleClearSearchResults} />
92
- </span>
105
+ {!collapsed && (
93
106
  <input
107
+ className={`${searchModifier}__input`}
94
108
  type="text"
95
109
  name="search"
96
- onChange={e => setSearchTerm(e.target.value)}
97
- onKeyPress={handleKeyPress}
98
- className="search-content--expanded__input"
99
110
  placeholder={placeholder}
100
111
  value={searchTerm}
101
- onBlur={handleOnBlur}
112
+ onChange={e => setSearchTerm(e.target.value)}
113
+ onKeyPress={handleKeyPress}
114
+ onFocus={() => setShowResults(true)}
115
+ data-testid="search-content-input"
102
116
  />
103
- </label>
104
- </div>
117
+ )}
118
+ </label>
119
+ </div>
120
+ {showResults && (
105
121
  <SearchContentResults
106
122
  results={results}
107
123
  debouncedSearchTerm={debouncedSearchTerm}
108
- handleClick={handleClick}
124
+ handleClick={handleNavigation}
109
125
  />
110
- </div>
111
- </>
126
+ )}
127
+ </div>
112
128
  );
113
129
  };
114
130
 
115
131
  SearchContent.propTypes = {
116
- searchInputAlignment: PropTypes.string,
117
132
  searchInputWrapperMobile: PropTypes.string,
118
133
  searchInputWrapperDesktop: PropTypes.string,
119
134
  placeholder: PropTypes.string,
@@ -124,7 +139,6 @@ SearchContent.propTypes = {
124
139
  };
125
140
 
126
141
  SearchContent.defaultProps = {
127
- searchInputAlignment: '',
128
142
  searchInputWrapperMobile: '',
129
143
  searchInputWrapperDesktop: '',
130
144
  placeholder: '',
@@ -3,25 +3,25 @@ import BlazeLink from '../BlazeLink';
3
3
  import SearchContentItems from './SearchContentItems';
4
4
 
5
5
  const SearchContentResults = ({ results, debouncedSearchTerm, onClick }) => {
6
- if (debouncedSearchTerm !== '') {
7
- return (
8
- <div className="search-content--results__wrapper">
9
- <div className="search-content--results__wrapper--message">
10
- <div className="search-content--results__content">
11
- {results.length === 0 && (
12
- <div className="search-content--results__message">
13
- <BlazeLink href={`/search?search_term=${debouncedSearchTerm}`}>
14
- {`Search all results for: ${debouncedSearchTerm}`}
15
- </BlazeLink>
16
- </div>
17
- )}
18
- {results.length > 0 && <SearchContentItems results={results} onClick={onClick} />}
19
- </div>
6
+ if (!debouncedSearchTerm) return null;
7
+ const hasResults = results.length > 0;
8
+ return (
9
+ <div className="search-content--results__wrapper">
10
+ <div className="search-content--results__wrapper--message">
11
+ <div className="search-content--results__content">
12
+ {hasResults ? (
13
+ <SearchContentItems results={results} onClick={onClick} />
14
+ ) : (
15
+ <div className="search-content--results__message">
16
+ <BlazeLink href={`/search?search_term=${debouncedSearchTerm}`}>
17
+ {`Search all results for: ${debouncedSearchTerm}`}
18
+ </BlazeLink>
19
+ </div>
20
+ )}
20
21
  </div>
21
22
  </div>
22
- );
23
- }
24
- return null;
23
+ </div>
24
+ );
25
25
  };
26
26
 
27
27
  export default SearchContentResults;
@@ -1,27 +1,14 @@
1
1
  import React from 'react';
2
+ import { CLOSE_ICON, SEARCH_ICON } from './constants';
2
3
 
3
- const SearchContentToggleIcon = ({ results, onClear }) => {
4
- if (results && results.length > 0) {
5
- return (
6
- <svg className="search-content--expanded__icon" viewBox="0 0 20 20" onClick={onClear}>
7
- <path
8
- fillRule="evenodd"
9
- d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z"
10
- clipRule="evenodd"
11
- />
12
- </svg>
13
- );
14
- }
15
-
16
- return (
17
- <svg className="search-content--expanded__icon" viewBox="0 0 20 20">
18
- <path
19
- fillRule="evenodd"
20
- d="M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z"
21
- clipRule="evenodd"
22
- />
23
- </svg>
24
- );
25
- };
4
+ const SearchContentToggleIcon = ({ onClick, useCloseIcon }) => (
5
+ <svg
6
+ className="search-content--expanded__icon"
7
+ viewBox="0 0 20 20"
8
+ onClick={onClick}
9
+ data-testid={useCloseIcon ? 'search-content-icon-close' : 'search-content-icon'}>
10
+ <path fillRule="evenodd" clipRule="evenodd" d={useCloseIcon ? CLOSE_ICON : SEARCH_ICON} />
11
+ </svg>
12
+ );
26
13
 
27
14
  export default SearchContentToggleIcon;
@@ -0,0 +1,6 @@
1
+ const SEARCH_ICON =
2
+ 'M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z';
3
+ const CLOSE_ICON =
4
+ 'M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z';
5
+
6
+ export { SEARCH_ICON, CLOSE_ICON };
@@ -2,6 +2,7 @@ import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import ErrorBoundary from '@blaze-cms/core-errors-ui';
4
4
  import getComponent from './getComponent';
5
+ import getVariant from './getVariant';
5
6
  import appendGtmClassName from './append-gtm-classname';
6
7
  import { PB_TYPE_IMAGE, PB_TYPE_BANNER, PB_TYPE_TEXTBLOCK, PB_TYPE_CAROUSEL } from './constants';
7
8
  import { BannerContextProvider } from '../../BannerContext';
@@ -24,16 +25,19 @@ const RenderComponent = ({
24
25
  const imageOptions = isImage ? imageProps : {};
25
26
  if (!Component) return null;
26
27
  const updatedSettings = appendGtmClassName(settings, childComponents);
28
+ const [VariantComponent, variantSettings] = getVariant(settings);
27
29
 
28
30
  return (
29
31
  <ErrorBoundary>
30
32
  <Component
31
33
  key={id}
32
34
  type={type}
35
+ VariantComponent={VariantComponent}
33
36
  {...options}
34
37
  {...imageOptions}
35
38
  {...nestedComponentsProps}
36
39
  {...updatedSettings}
40
+ {...variantSettings}
37
41
  name={name || settings.name}>
38
42
  {hasTextBlockBanners ? (
39
43
  <BannerContextProvider siblings={siblings} banners={textBlockBanners} pbOptions={options}>