@thecb/components 11.2.17 → 11.3.0-beta.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thecb/components",
3
- "version": "11.2.17",
3
+ "version": "11.3.0-beta.0",
4
4
  "description": "Common lib for CityBase react components",
5
5
  "main": "dist/index.cjs.js",
6
6
  "typings": "dist/index.d.ts",
@@ -2,17 +2,14 @@ import React, { useContext } from "react";
2
2
  import { ThemeContext } from "styled-components";
3
3
 
4
4
  import ButtonWithLink from "../button-with-link";
5
- import Spinner from "../spinner";
6
5
  import { Box, Cluster, Center, Cover, Switcher } from "../layouts";
7
6
  import Heading from "../heading";
8
7
  import Title from "../title";
9
8
  import withWindowSize from "../../withWindowSize";
10
- import { WHITE } from "../../../constants/colors";
11
9
 
12
10
  const Jumbo = ({
13
11
  showButton,
14
12
  heading,
15
- isHeadingLoading = false,
16
13
  buttonLink,
17
14
  subHeading,
18
15
  buttonText,
@@ -58,28 +55,16 @@ const Jumbo = ({
58
55
  <Title
59
56
  variant={isMobile ? "small" : "large"}
60
57
  as="h1"
61
- color={WHITE}
58
+ color="#ffffff"
62
59
  className="themeJumboHeading"
63
60
  extraStyles={showCartStatus && isMobile && `max-width: 60%;`}
64
61
  >
65
- {isHeadingLoading ? (
66
- <Spinner
67
- size="50"
68
- cx="25"
69
- cy="25"
70
- radius="12.5"
71
- strokeWidth="3"
72
- centerSpinner
73
- color={WHITE}
74
- />
75
- ) : (
76
- heading
77
- )}
62
+ {heading}
78
63
  </Title>
79
64
  {subHeading && (
80
65
  <Heading
81
66
  variant={isMobile ? "h6" : "h2"}
82
- color={WHITE}
67
+ color="#ffffff"
83
68
  className="themeJumboSubheading"
84
69
  >
85
70
  {subHeading}
@@ -65,7 +65,6 @@ const Spinner = ({
65
65
  size = "24",
66
66
  centerSpinner = false,
67
67
  themeValues,
68
- color = themeValues.color,
69
68
  cx = "50",
70
69
  cy = "50",
71
70
  radius = "25",
@@ -74,7 +73,7 @@ const Spinner = ({
74
73
  <SpinnerContainer centerSpinner={centerSpinner} size={size}>
75
74
  <SpinnerSvgAnimation
76
75
  size={size}
77
- color={color}
76
+ color={themeValues.color}
78
77
  centerSpinner={centerSpinner}
79
78
  >
80
79
  <circle
@@ -46,3 +46,4 @@ export { default as PopupMenu } from "./popup-menu";
46
46
  export { default as MultipleSelectFilter } from "./multiple-select-filter";
47
47
  export { default as ContactCard } from "./contact-card";
48
48
  export { default as HeroImage } from "./hero-image";
49
+ export { default as TurnstileWidget } from "./turnstile-widget/TurnstileWidget";
@@ -0,0 +1,86 @@
1
+ import React, {
2
+ useState,
3
+ useEffect,
4
+ useRef,
5
+ forwardRef,
6
+ useImperativeHandle
7
+ } from "react";
8
+ import { Box } from "../../atoms/layouts";
9
+ import styled from "styled-components";
10
+ import { useTurnstileScript } from "../../../hooks";
11
+ import { noop } from "../../../util/general";
12
+
13
+ const TurnstileWidgetContainer = styled(Box)`
14
+ display: flex;
15
+ padding: ${({ padding }) => padding};
16
+ justify-content: ${({ justify }) => justify};
17
+ width: 100%;
18
+ `;
19
+
20
+ const TurnstileWidget = forwardRef(
21
+ (
22
+ {
23
+ verifyURL, // URL to load the Turnstile script from
24
+ siteKey, // Turnstile site key
25
+ onSuccess = noop,
26
+ onError = noop,
27
+ onExpired = noop,
28
+ padding = "1rem",
29
+ justify = "flex-end",
30
+ size = "normal",
31
+ tabindex = 0,
32
+ retry = "auto",
33
+ theme = "auto",
34
+ extraStyles = ""
35
+ },
36
+ ref
37
+ ) => {
38
+ if (!verifyURL || !siteKey) return null;
39
+
40
+ const containerRef = useRef(null);
41
+ const [widgetId, setWidgetId] = useState(null);
42
+ const isTurnstileLoaded = useTurnstileScript(verifyURL);
43
+
44
+ // Allow the parent component to reset the Turnstile widget
45
+ useImperativeHandle(ref, () => ({
46
+ reset: () => {
47
+ if (widgetId !== null) {
48
+ window.turnstile?.reset(widgetId);
49
+ }
50
+ }
51
+ }));
52
+
53
+ useEffect(() => {
54
+ if (window.turnstile && containerRef.current && widgetId === null) {
55
+ const newWidgetId = window.turnstile.render(containerRef.current, {
56
+ sitekey: siteKey,
57
+ size: size,
58
+ retry: retry,
59
+ tabindex: tabindex,
60
+ theme: theme,
61
+ callback: token => onSuccess(token),
62
+ "error-callback": () => onError(),
63
+ "expired-callback": () => onExpired()
64
+ });
65
+ setWidgetId(newWidgetId);
66
+ }
67
+ return () => {
68
+ if (widgetId !== null) {
69
+ window.turnstile?.reset(widgetId);
70
+ }
71
+ };
72
+ }, [isTurnstileLoaded, siteKey, widgetId]);
73
+
74
+ return (
75
+ <TurnstileWidgetContainer
76
+ padding={padding}
77
+ justify={justify}
78
+ extraStyles={extraStyles}
79
+ >
80
+ <div ref={containerRef} />
81
+ </TurnstileWidgetContainer>
82
+ );
83
+ }
84
+ );
85
+
86
+ export default TurnstileWidget;
@@ -0,0 +1,3 @@
1
+ import TurnstileWidget from "./TurnstileWidget";
2
+
3
+ export default TurnstileWidget;
@@ -2,3 +2,4 @@ export { default as useOutsideClick } from "./use-outside-click";
2
2
  export { default as useScrollTo } from "./use-scroll-to";
3
3
  export { default as useToastNotification } from "./use-toast-notification";
4
4
  export { default as useConditionallyAddValidator } from "./use-conditionally-add-validator";
5
+ export { default as useTurnstileScript } from "./use-turnstile-script";
@@ -0,0 +1,36 @@
1
+ import { useEffect, useState } from "react";
2
+
3
+ /**
4
+ * A custom hook to dynamically load the Cloudflare Turnstile script.
5
+ *
6
+ * @param {string} verifyURL - The URL of the Turnstile verification script.
7
+ */
8
+ const useTurnstileScript = verifyURL => {
9
+ const [isLoaded, setIsLoaded] = useState(false);
10
+
11
+ useEffect(() => {
12
+ if (typeof window === "undefined") {
13
+ setIsLoaded(false);
14
+ return;
15
+ }
16
+ if (window.turnstile && window.turnstile.render) {
17
+ setIsLoaded(true);
18
+ return;
19
+ }
20
+
21
+ const script = document.createElement("script");
22
+ script.src = `${verifyURL}?render=explicit`;
23
+ script.onload = () => {
24
+ setIsLoaded(true);
25
+ };
26
+ script.defer = true;
27
+ document.getElementsByTagName("head")[0].appendChild(script);
28
+
29
+ return () => {
30
+ setIsLoaded(false);
31
+ };
32
+ }, [verifyURL]);
33
+
34
+ return isLoaded;
35
+ };
36
+ export default useTurnstileScript;
Binary file