@prosopo/procaptcha-react 2.9.96 → 2.9.97

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,230 +1,166 @@
1
+ import { CaptchaWidget } from "./CaptchaWidget.js";
2
+ import addDataAttr from "../util/index.js";
3
+ import Button from "./Button.js";
4
+ import { darkTheme, lightTheme } from "@prosopo/widget-skeleton";
5
+ import { Suspense, useMemo } from "react";
1
6
  import { jsx, jsxs } from "@emotion/react/jsx-runtime";
2
7
  import { useTranslation } from "@prosopo/locale";
3
8
  import { ReloadButton } from "@prosopo/procaptcha-common";
4
9
  import { at } from "@prosopo/util";
5
- import { lightTheme, darkTheme } from "@prosopo/widget-skeleton";
6
- import { useMemo, Suspense } from "react";
7
- import addDataAttr from "../util/index.js";
8
- import Button from "./Button.js";
9
- import { CaptchaWidget } from "./CaptchaWidget.js";
10
- const CaptchaComponent = ({
11
- challenge,
12
- index,
13
- solutions,
14
- onSubmit,
15
- onCancel,
16
- onClick,
17
- onNext,
18
- onReload,
19
- themeColor
20
- }) => {
21
- const { t } = useTranslation();
22
- const captcha = challenge.captchas ? at(challenge.captchas, index) : null;
23
- const solution = solutions ? at(solutions, index) : [];
24
- const theme = useMemo(
25
- () => themeColor === "light" ? lightTheme : darkTheme,
26
- [themeColor]
27
- );
28
- const doubleSpacing = `${theme.spacing.unit * 2}px`;
29
- const fullSpacing = `${theme.spacing.unit}px`;
30
- const halfSpacing = `${theme.spacing.half}px`;
31
- return /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx("div", { children: "Loading..." }), children: /* @__PURE__ */ jsx(
32
- "div",
33
- {
34
- style: {
35
- // introduce scroll bars when screen < minWidth of children
36
- overflowX: "auto",
37
- overflowY: "auto",
38
- maxWidth: "500px",
39
- maxHeight: "100%",
40
- display: "flex",
41
- flexDirection: "column",
42
- border: "1px solid #dddddd",
43
- boxShadow: "rgba(255, 255, 255, 0.2) 0px 0px 4px",
44
- borderRadius: "4px",
45
- backgroundColor: theme.palette.background.default,
46
- userSelect: "none",
47
- touchAction: "none",
48
- overscrollBehavior: "none"
49
- },
50
- children: /* @__PURE__ */ jsxs(
51
- "div",
52
- {
53
- style: {
54
- backgroundColor: theme.palette.background.default,
55
- display: "flex",
56
- flexDirection: "column",
57
- minWidth: "300px",
58
- marginLeft: fullSpacing,
59
- marginRight: fullSpacing,
60
- justifyContent: "center"
61
- },
62
- children: [
63
- /* @__PURE__ */ jsx(
64
- "div",
65
- {
66
- style: {
67
- display: "flex",
68
- alignItems: "center",
69
- width: "100%"
70
- },
71
- children: /* @__PURE__ */ jsx(
72
- "div",
73
- {
74
- style: {
75
- backgroundColor: theme.palette.primary.main,
76
- width: "100%",
77
- marginTop: fullSpacing
78
- },
79
- children: /* @__PURE__ */ jsxs(
80
- "div",
81
- {
82
- style: {
83
- padding: `${theme.spacing.half}px`,
84
- fontFamily: theme.font.fontFamily
85
- },
86
- children: [
87
- /* @__PURE__ */ jsxs(
88
- "p",
89
- {
90
- style: {
91
- color: "#ffffff",
92
- fontWeight: 700,
93
- lineHeight: 1.5
94
- },
95
- children: [
96
- t("WIDGET.SELECT_ALL"),
97
- ":",
98
- " ",
99
- /* @__PURE__ */ jsx("span", { children: `${at(challenge.captchas, index).target} ` })
100
- ]
101
- }
102
- ),
103
- /* @__PURE__ */ jsx(
104
- "p",
105
- {
106
- style: {
107
- color: "#ffffff",
108
- fontWeight: 500,
109
- lineHeight: 0.8,
110
- fontSize: "0.8rem"
111
- },
112
- children: t("WIDGET.IF_NONE_CLICK_NEXT")
113
- }
114
- )
115
- ]
116
- }
117
- )
118
- }
119
- )
120
- }
121
- ),
122
- /* @__PURE__ */ jsx(
123
- "div",
124
- {
125
- ...addDataAttr({ dev: { cy: `captcha-${index}` } }),
126
- style: { overflow: "hidden" },
127
- children: captcha && /* @__PURE__ */ jsx(
128
- CaptchaWidget,
129
- {
130
- challenge: captcha,
131
- solution,
132
- onClick,
133
- themeColor
134
- }
135
- )
136
- }
137
- ),
138
- /* @__PURE__ */ jsx(
139
- "div",
140
- {
141
- style: {
142
- display: "flex",
143
- alignItems: "center",
144
- justifyContent: "space-between",
145
- lineHeight: 1.75,
146
- padding: `${fullSpacing} 0 ${doubleSpacing} 0`
147
- },
148
- children: /* @__PURE__ */ jsxs(
149
- "div",
150
- {
151
- style: {
152
- // expand to full height / width of parent
153
- width: "100%",
154
- height: "100%",
155
- // display children in flex, spreading them evenly
156
- display: "flex",
157
- flexDirection: "row",
158
- justifyContent: "space-between",
159
- gap: "10px"
160
- },
161
- children: [
162
- /* @__PURE__ */ jsx(
163
- "div",
164
- {
165
- style: {
166
- position: "relative",
167
- flexGrow: 1,
168
- // make the width of each item 1/3rd of the width overall, i.e. 3 columns
169
- flexBasis: "calc(33.333% - 10px)"
170
- },
171
- children: /* @__PURE__ */ jsx(
172
- Button,
173
- {
174
- themeColor,
175
- buttonType: "cancel",
176
- onClick: onCancel,
177
- text: t("WIDGET.CANCEL"),
178
- "aria-label": t("WIDGET.CANCEL")
179
- }
180
- )
181
- }
182
- ),
183
- /* @__PURE__ */ jsx(
184
- "div",
185
- {
186
- style: {
187
- position: "relative",
188
- flexGrow: 1,
189
- // make the width of each item 1/3rd of the width overall, i.e. 3 columns
190
- flexBasis: "calc(33.333% - 10px)"
191
- },
192
- children: /* @__PURE__ */ jsx(ReloadButton, { themeColor, onReload })
193
- }
194
- ),
195
- /* @__PURE__ */ jsx(
196
- "div",
197
- {
198
- style: {
199
- position: "relative",
200
- flexGrow: 1,
201
- // make the width of each item 1/3rd of the width overall, i.e. 3 columns
202
- flexBasis: "calc(33.333% - 10px)"
203
- },
204
- children: /* @__PURE__ */ jsx(
205
- Button,
206
- {
207
- themeColor,
208
- buttonType: "next",
209
- text: index < challenge.captchas.length - 1 ? t("WIDGET.NEXT") : t("WIDGET.SUBMIT"),
210
- onClick: index < challenge.captchas.length - 1 ? onNext : onSubmit,
211
- "aria-label": index < challenge.captchas.length - 1 ? t("WIDGET.NEXT") : t("WIDGET.SUBMIT"),
212
- "data-cy": "button-next"
213
- }
214
- )
215
- }
216
- )
217
- ]
218
- }
219
- )
220
- }
221
- )
222
- ]
223
- }
224
- )
225
- }
226
- ) });
227
- };
228
- export {
229
- CaptchaComponent as default
10
+ //#region src/components/CaptchaComponent.tsx
11
+ var CaptchaComponent = ({ challenge, index, solutions, onSubmit, onCancel, onClick, onNext, onReload, themeColor }) => {
12
+ const { t } = useTranslation();
13
+ const captcha = challenge.captchas ? at(challenge.captchas, index) : null;
14
+ const solution = solutions ? at(solutions, index) : [];
15
+ const theme = useMemo(() => themeColor === "light" ? lightTheme : darkTheme, [themeColor]);
16
+ const doubleSpacing = `${theme.spacing.unit * 2}px`;
17
+ const fullSpacing = `${theme.spacing.unit}px`;
18
+ `${theme.spacing.half}`;
19
+ return /* @__PURE__ */ jsx(Suspense, {
20
+ fallback: /* @__PURE__ */ jsx("div", { children: "Loading..." }),
21
+ children: /* @__PURE__ */ jsx("div", {
22
+ style: {
23
+ overflowX: "auto",
24
+ overflowY: "auto",
25
+ maxWidth: "500px",
26
+ maxHeight: "100%",
27
+ display: "flex",
28
+ flexDirection: "column",
29
+ border: "1px solid #dddddd",
30
+ boxShadow: "rgba(255, 255, 255, 0.2) 0px 0px 4px",
31
+ borderRadius: "4px",
32
+ backgroundColor: theme.palette.background.default,
33
+ userSelect: "none",
34
+ touchAction: "none",
35
+ overscrollBehavior: "none"
36
+ },
37
+ children: /* @__PURE__ */ jsxs("div", {
38
+ style: {
39
+ backgroundColor: theme.palette.background.default,
40
+ display: "flex",
41
+ flexDirection: "column",
42
+ minWidth: "300px",
43
+ marginLeft: fullSpacing,
44
+ marginRight: fullSpacing,
45
+ justifyContent: "center"
46
+ },
47
+ children: [
48
+ /* @__PURE__ */ jsx("div", {
49
+ style: {
50
+ display: "flex",
51
+ alignItems: "center",
52
+ width: "100%"
53
+ },
54
+ children: /* @__PURE__ */ jsx("div", {
55
+ style: {
56
+ backgroundColor: theme.palette.primary.main,
57
+ width: "100%",
58
+ marginTop: fullSpacing
59
+ },
60
+ children: /* @__PURE__ */ jsxs("div", {
61
+ style: {
62
+ padding: `${theme.spacing.half}px`,
63
+ fontFamily: theme.font.fontFamily
64
+ },
65
+ children: [/* @__PURE__ */ jsxs("p", {
66
+ style: {
67
+ color: "#ffffff",
68
+ fontWeight: 700,
69
+ lineHeight: 1.5
70
+ },
71
+ children: [
72
+ t("WIDGET.SELECT_ALL"),
73
+ ":",
74
+ "\xA0",
75
+ /* @__PURE__ */ jsx("span", { children: `${at(challenge.captchas, index).target} ` })
76
+ ]
77
+ }), /* @__PURE__ */ jsx("p", {
78
+ style: {
79
+ color: "#ffffff",
80
+ fontWeight: 500,
81
+ lineHeight: .8,
82
+ fontSize: "0.8rem"
83
+ },
84
+ children: t("WIDGET.IF_NONE_CLICK_NEXT")
85
+ })]
86
+ })
87
+ })
88
+ }),
89
+ /* @__PURE__ */ jsx("div", {
90
+ ...addDataAttr({ dev: { cy: `captcha-${index}` } }),
91
+ style: { overflow: "hidden" },
92
+ children: captcha && /* @__PURE__ */ jsx(CaptchaWidget, {
93
+ challenge: captcha,
94
+ solution,
95
+ onClick,
96
+ themeColor
97
+ })
98
+ }),
99
+ /* @__PURE__ */ jsx("div", {
100
+ style: {
101
+ display: "flex",
102
+ alignItems: "center",
103
+ justifyContent: "space-between",
104
+ lineHeight: 1.75,
105
+ padding: `${fullSpacing} 0 ${doubleSpacing} 0`
106
+ },
107
+ children: /* @__PURE__ */ jsxs("div", {
108
+ style: {
109
+ width: "100%",
110
+ height: "100%",
111
+ display: "flex",
112
+ flexDirection: "row",
113
+ justifyContent: "space-between",
114
+ gap: "10px"
115
+ },
116
+ children: [
117
+ /* @__PURE__ */ jsx("div", {
118
+ style: {
119
+ position: "relative",
120
+ flexGrow: 1,
121
+ flexBasis: "calc(33.333% - 10px)"
122
+ },
123
+ children: /* @__PURE__ */ jsx(Button, {
124
+ themeColor,
125
+ buttonType: "cancel",
126
+ onClick: onCancel,
127
+ text: t("WIDGET.CANCEL"),
128
+ "aria-label": t("WIDGET.CANCEL")
129
+ })
130
+ }),
131
+ /* @__PURE__ */ jsx("div", {
132
+ style: {
133
+ position: "relative",
134
+ flexGrow: 1,
135
+ flexBasis: "calc(33.333% - 10px)"
136
+ },
137
+ children: /* @__PURE__ */ jsx(ReloadButton, {
138
+ themeColor,
139
+ onReload
140
+ })
141
+ }),
142
+ /* @__PURE__ */ jsx("div", {
143
+ style: {
144
+ position: "relative",
145
+ flexGrow: 1,
146
+ flexBasis: "calc(33.333% - 10px)"
147
+ },
148
+ children: /* @__PURE__ */ jsx(Button, {
149
+ themeColor,
150
+ buttonType: "next",
151
+ text: index < challenge.captchas.length - 1 ? t("WIDGET.NEXT") : t("WIDGET.SUBMIT"),
152
+ onClick: index < challenge.captchas.length - 1 ? onNext : onSubmit,
153
+ "aria-label": index < challenge.captchas.length - 1 ? t("WIDGET.NEXT") : t("WIDGET.SUBMIT"),
154
+ "data-cy": "button-next"
155
+ })
156
+ })
157
+ ]
158
+ })
159
+ })
160
+ ]
161
+ })
162
+ })
163
+ });
230
164
  };
165
+ //#endregion
166
+ export { CaptchaComponent as default };
@@ -1,161 +1,115 @@
1
- import { jsx, jsxs } from "@emotion/react/jsx-runtime";
2
1
  import { ProsopoDatasetError } from "@prosopo/common";
3
- import { lightTheme, darkTheme } from "@prosopo/widget-skeleton";
2
+ import { darkTheme, lightTheme } from "@prosopo/widget-skeleton";
4
3
  import { useMemo } from "react";
5
- const getHash = (item) => {
6
- if (!item.hash) {
7
- throw new ProsopoDatasetError("CAPTCHA.MISSING_ITEM_HASH", {
8
- context: { item }
9
- });
10
- }
11
- return item.hash;
12
- };
13
- const CaptchaWidget = ({
14
- challenge,
15
- solution,
16
- onClick,
17
- themeColor
18
- }) => {
19
- const items = challenge.items;
20
- const theme = useMemo(
21
- () => themeColor === "light" ? lightTheme : darkTheme,
22
- [themeColor]
23
- );
24
- const fullSpacing = `${theme.spacing.unit}px`;
25
- const halfSpacing = `${theme.spacing.half}px`;
26
- return /* @__PURE__ */ jsx(
27
- "div",
28
- {
29
- style: {
30
- // expand to full height / width of parent
31
- width: "100%",
32
- height: "100%",
33
- // display children in flex, spreading them evenly and wrapping when row length exceeded
34
- display: "flex",
35
- flexDirection: "row",
36
- flexWrap: "wrap",
37
- justifyContent: "space-between",
38
- paddingBottom: fullSpacing,
39
- paddingTop: fullSpacing,
40
- gap: "10px"
41
- },
42
- children: items.map((item, index) => {
43
- const hash = getHash(item);
44
- const imageStyle = {
45
- // enable the items in the grid to grow in width to use up excess space
46
- flexGrow: 1,
47
- // make the width of each item 1/3rd of the width overall, i.e. 3 columns
48
- flexBasis: "calc(33.333% - 10px)",
49
- // include the padding / margin / border in the width
50
- boxSizing: "border-box"
51
- };
52
- return /* @__PURE__ */ jsx("div", { style: imageStyle, children: /* @__PURE__ */ jsxs(
53
- "div",
54
- {
55
- style: {
56
- position: "relative",
57
- cursor: "pointer",
58
- height: "100%",
59
- width: "100%",
60
- padding: 0,
61
- margin: 0
62
- },
63
- onClick: (e) => {
64
- if (!e.isTrusted) {
65
- return;
66
- }
67
- if ("touches" in e && e.touches.length > 0 && e.touches[0]) {
68
- onClick(hash, e.touches[0].clientX, e.touches[0].clientY);
69
- return;
70
- }
71
- if ("clientX" in e && "clientY" in e) {
72
- onClick(hash, e.clientX, e.clientY);
73
- return;
74
- }
75
- onClick(hash, 0, 0);
76
- },
77
- children: [
78
- /* @__PURE__ */ jsx(
79
- "img",
80
- {
81
- style: {
82
- width: "100%",
83
- // image should be full width / height of the item
84
- display: "block",
85
- // removes whitespace below imgs
86
- objectFit: "cover",
87
- // contain the entire image in the img tag
88
- aspectRatio: "1/1",
89
- // force AR to be 1, letterboxing images with different aspect ratios
90
- height: "auto",
91
- // make the img tag responsive to its container
92
- overflow: "hidden",
93
- borderStyle: "solid",
94
- borderWidth: "1px",
95
- borderColor: theme.palette.grey[300]
96
- },
97
- src: item.data,
98
- alt: `Captcha image ${index + 1}`,
99
- onError: (e) => {
100
- const target = e.currentTarget;
101
- target._retryCount = (target._retryCount || 0) + 1;
102
- if (target._retryCount <= 3) {
103
- target.src = `${item.data}?retry=${Date.now()}`;
104
- }
105
- }
106
- }
107
- ),
108
- /* @__PURE__ */ jsx(
109
- "div",
110
- {
111
- style: {
112
- position: "absolute",
113
- top: 0,
114
- left: 0,
115
- bottom: 0,
116
- right: 0,
117
- height: "100%",
118
- width: "100%",
119
- // display overlays in center
120
- display: "flex",
121
- alignItems: "center",
122
- justifyContent: "center",
123
- // make bg half opacity, i.e. shadowing the item's img
124
- backgroundColor: "rgba(0,0,0,0.5)",
125
- visibility: solution.some((s) => s[0] === hash) ? "visible" : "hidden"
126
- },
127
- children: /* @__PURE__ */ jsx(
128
- "svg",
129
- {
130
- style: {
131
- backgroundColor: "transparent",
132
- // img must be displayed as block otherwise gets a bottom whitespace border
133
- display: "block",
134
- // how big the overlay icon is
135
- width: "35%",
136
- height: "35%",
137
- transition: "fill 200ms cubic-bezier(0.4, 0, 0.2, 1) 0ms",
138
- userSelect: "none",
139
- fill: "currentcolor"
140
- },
141
- focusable: "false",
142
- color: "#fff",
143
- "aria-hidden": "true",
144
- viewBox: "0 0 24 24",
145
- "data-testid": "CheckIcon",
146
- "aria-label": "Check icon",
147
- children: /* @__PURE__ */ jsx("path", { d: "M9 16.17 4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z" })
148
- }
149
- )
150
- }
151
- )
152
- ]
153
- }
154
- ) }, item.hash);
155
- })
156
- }
157
- );
4
+ import { jsx, jsxs } from "@emotion/react/jsx-runtime";
5
+ //#region src/components/CaptchaWidget.tsx
6
+ var getHash = (item) => {
7
+ if (!item.hash) throw new ProsopoDatasetError("CAPTCHA.MISSING_ITEM_HASH", { context: { item } });
8
+ return item.hash;
158
9
  };
159
- export {
160
- CaptchaWidget
10
+ var CaptchaWidget = ({ challenge, solution, onClick, themeColor }) => {
11
+ const items = challenge.items;
12
+ const theme = useMemo(() => themeColor === "light" ? lightTheme : darkTheme, [themeColor]);
13
+ const fullSpacing = `${theme.spacing.unit}px`;
14
+ `${theme.spacing.half}`;
15
+ return /* @__PURE__ */ jsx("div", {
16
+ style: {
17
+ width: "100%",
18
+ height: "100%",
19
+ display: "flex",
20
+ flexDirection: "row",
21
+ flexWrap: "wrap",
22
+ justifyContent: "space-between",
23
+ paddingBottom: fullSpacing,
24
+ paddingTop: fullSpacing,
25
+ gap: "10px"
26
+ },
27
+ children: items.map((item, index) => {
28
+ const hash = getHash(item);
29
+ return /* @__PURE__ */ jsx("div", {
30
+ style: {
31
+ flexGrow: 1,
32
+ flexBasis: "calc(33.333% - 10px)",
33
+ boxSizing: "border-box"
34
+ },
35
+ children: /* @__PURE__ */ jsxs("div", {
36
+ style: {
37
+ position: "relative",
38
+ cursor: "pointer",
39
+ height: "100%",
40
+ width: "100%",
41
+ padding: 0,
42
+ margin: 0
43
+ },
44
+ onClick: (e) => {
45
+ if (!e.isTrusted) return;
46
+ if ("touches" in e && e.touches.length > 0 && e.touches[0]) {
47
+ onClick(hash, e.touches[0].clientX, e.touches[0].clientY);
48
+ return;
49
+ }
50
+ if ("clientX" in e && "clientY" in e) {
51
+ onClick(hash, e.clientX, e.clientY);
52
+ return;
53
+ }
54
+ onClick(hash, 0, 0);
55
+ },
56
+ children: [/* @__PURE__ */ jsx("img", {
57
+ style: {
58
+ width: "100%",
59
+ display: "block",
60
+ objectFit: "cover",
61
+ aspectRatio: "1/1",
62
+ height: "auto",
63
+ overflow: "hidden",
64
+ borderStyle: "solid",
65
+ borderWidth: "1px",
66
+ borderColor: theme.palette.grey[300]
67
+ },
68
+ src: item.data,
69
+ alt: `Captcha image ${index + 1}`,
70
+ onError: (e) => {
71
+ const target = e.currentTarget;
72
+ target._retryCount = (target._retryCount || 0) + 1;
73
+ if (target._retryCount <= 3) target.src = `${item.data}?retry=${Date.now()}`;
74
+ }
75
+ }), /* @__PURE__ */ jsx("div", {
76
+ style: {
77
+ position: "absolute",
78
+ top: 0,
79
+ left: 0,
80
+ bottom: 0,
81
+ right: 0,
82
+ height: "100%",
83
+ width: "100%",
84
+ display: "flex",
85
+ alignItems: "center",
86
+ justifyContent: "center",
87
+ backgroundColor: "rgba(0,0,0,0.5)",
88
+ visibility: solution.some((s) => s[0] === hash) ? "visible" : "hidden"
89
+ },
90
+ children: /* @__PURE__ */ jsx("svg", {
91
+ style: {
92
+ backgroundColor: "transparent",
93
+ display: "block",
94
+ width: "35%",
95
+ height: "35%",
96
+ transition: "fill 200ms cubic-bezier(0.4, 0, 0.2, 1) 0ms",
97
+ userSelect: "none",
98
+ fill: "currentcolor"
99
+ },
100
+ focusable: "false",
101
+ color: "#fff",
102
+ "aria-hidden": "true",
103
+ viewBox: "0 0 24 24",
104
+ "data-testid": "CheckIcon",
105
+ "aria-label": "Check icon",
106
+ children: /* @__PURE__ */ jsx("path", { d: "M9 16.17 4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z" })
107
+ })
108
+ })]
109
+ })
110
+ }, item.hash);
111
+ })
112
+ });
161
113
  };
114
+ //#endregion
115
+ export { CaptchaWidget };