@smileid/web-components 11.0.0 → 11.0.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 (141) hide show
  1. package/README.md +15 -15
  2. package/dist/README.md +15 -0
  3. package/dist/components/README.md +14 -0
  4. package/dist/components/document/src/README.md +111 -0
  5. package/dist/components/document/src/document-capture/README.md +90 -0
  6. package/dist/components/document/src/document-capture-instructions/README.md +56 -0
  7. package/dist/components/document/src/document-capture-review/README.md +79 -0
  8. package/dist/components/selfie/README.md +225 -0
  9. package/dist/components/smart-camera-web/src/README.md +207 -0
  10. package/dist/domain/camera/src/README.md +38 -0
  11. package/dist/domain/file-upload/README.md +35 -0
  12. package/dist/esm/{DocumentCaptureScreens-RECPb0wH.js → DocumentCaptureScreens-DmH2JZDA.js} +2 -2
  13. package/dist/esm/DocumentCaptureScreens-DmH2JZDA.js.map +1 -0
  14. package/dist/esm/EndUserConsent-D4fd1ovG.js.map +1 -1
  15. package/dist/esm/Navigation-CTjK6tLU.js.map +1 -1
  16. package/dist/esm/PoweredBySmileId-CxbaihMu.js.map +1 -1
  17. package/dist/esm/{SelfieCaptureScreens-CqBVGEJk.js → SelfieCaptureScreens-DbdN2zNk.js} +2 -2
  18. package/dist/esm/SelfieCaptureScreens-DbdN2zNk.js.map +1 -0
  19. package/dist/esm/SignaturePad-C7MtmT8m.js.map +1 -1
  20. package/dist/esm/TotpConsent-CQU5jQi4.js.map +1 -1
  21. package/dist/esm/combobox.js.map +1 -1
  22. package/dist/esm/document.js +1 -1
  23. package/dist/esm/main.js +2 -2
  24. package/dist/esm/{package-BDJnoIAU.js → package-bgeQiff6.js} +2 -2
  25. package/dist/esm/package-bgeQiff6.js.map +1 -0
  26. package/dist/esm/selfie.js +1 -1
  27. package/dist/esm/smart-camera-web.js +3 -3
  28. package/dist/esm/smart-camera-web.js.map +1 -1
  29. package/dist/esm/styles-BOEZtbuc.js.map +1 -1
  30. package/dist/package-lock.json +4948 -0
  31. package/dist/package.json +59 -0
  32. package/dist/smart-camera-web.js +1 -1
  33. package/dist/smart-camera-web.js.gz +0 -0
  34. package/dist/smart-camera-web.js.map +1 -1
  35. package/dist/src/components/combobox/src/index.js +2 -0
  36. package/dist/src/components/combobox/src/index.js.map +7 -0
  37. package/dist/src/components/document/src/index.js +2 -0
  38. package/dist/src/components/document/src/index.js.map +7 -0
  39. package/dist/src/components/end-user-consent/src/index.js +14 -0
  40. package/dist/src/components/end-user-consent/src/index.js.map +7 -0
  41. package/dist/src/components/selfie/src/index.js +2 -0
  42. package/dist/src/components/selfie/src/index.js.map +7 -0
  43. package/dist/src/components/signature-pad/src/index.js +10 -0
  44. package/dist/src/components/signature-pad/src/index.js.map +7 -0
  45. package/dist/src/components/smart-camera-web/src/SmartCameraWeb.js +2 -0
  46. package/dist/src/components/smart-camera-web/src/SmartCameraWeb.js.map +7 -0
  47. package/dist/src/components/totp-consent/src/index.js +14 -0
  48. package/dist/src/components/totp-consent/src/index.js.map +7 -0
  49. package/dist/src/index.js.map +7 -0
  50. package/dist/styles/README.md +3 -0
  51. package/dist/types/combobox.d.ts +19 -19
  52. package/dist/types/document.d.ts +19 -19
  53. package/dist/types/end-user-consent.d.ts +19 -19
  54. package/dist/types/main.d.ts +24 -20
  55. package/dist/types/navigation.d.ts +19 -19
  56. package/dist/types/selfie.d.ts +19 -19
  57. package/dist/types/signature-pad.d.ts +19 -19
  58. package/dist/types/smart-camera-web.d.ts +19 -19
  59. package/dist/types/totp-consent.d.ts +19 -19
  60. package/lib/components/README.md +14 -14
  61. package/lib/components/attribution/PoweredBySmileId.js +42 -42
  62. package/lib/components/camera-permission/CameraPermission.js +139 -139
  63. package/lib/components/camera-permission/CameraPermission.stories.js +27 -27
  64. package/lib/components/combobox/src/Combobox.js +589 -589
  65. package/lib/components/combobox/src/index.js +1 -1
  66. package/lib/components/document/src/DocumentCaptureScreens.js +410 -410
  67. package/lib/components/document/src/DocumentCaptureScreens.stories.js +57 -57
  68. package/lib/components/document/src/README.md +111 -111
  69. package/lib/components/document/src/document-capture/DocumentCapture.js +760 -760
  70. package/lib/components/document/src/document-capture/DocumentCapture.stories.js +78 -78
  71. package/lib/components/document/src/document-capture/README.md +90 -90
  72. package/lib/components/document/src/document-capture/index.js +3 -3
  73. package/lib/components/document/src/document-capture-instructions/DocumentCaptureInstructions.js +545 -545
  74. package/lib/components/document/src/document-capture-instructions/DocumentCaptureInstructions.stories.js +24 -24
  75. package/lib/components/document/src/document-capture-instructions/README.md +56 -56
  76. package/lib/components/document/src/document-capture-instructions/index.js +3 -3
  77. package/lib/components/document/src/document-capture-review/DocumentCaptureReview.js +360 -360
  78. package/lib/components/document/src/document-capture-review/DocumentCaptureReview.stories.js +24 -24
  79. package/lib/components/document/src/document-capture-review/README.md +79 -79
  80. package/lib/components/document/src/document-capture-review/index.js +3 -3
  81. package/lib/components/document/src/index.js +3 -3
  82. package/lib/components/end-user-consent/src/EndUserConsent.js +795 -795
  83. package/lib/components/end-user-consent/src/EndUserConsent.stories.js +29 -29
  84. package/lib/components/end-user-consent/src/index.js +4 -4
  85. package/lib/components/navigation/src/Navigation.js +171 -171
  86. package/lib/components/navigation/src/Navigation.stories.js +24 -24
  87. package/lib/components/navigation/src/index.js +3 -3
  88. package/lib/components/selfie/README.md +225 -225
  89. package/lib/components/selfie/src/SelfieCaptureScreens.js +420 -420
  90. package/lib/components/selfie/src/SelfieCaptureScreens.stories.js +29 -29
  91. package/lib/components/selfie/src/index.js +3 -3
  92. package/lib/components/selfie/src/selfie-capture/SelfieCapture.js +1099 -1099
  93. package/lib/components/selfie/src/selfie-capture/SelfieCapture.stories.js +36 -36
  94. package/lib/components/selfie/src/selfie-capture/index.js +3 -3
  95. package/lib/components/selfie/src/selfie-capture-instructions/SelfieCaptureInstructions.js +689 -689
  96. package/lib/components/selfie/src/selfie-capture-instructions/SelfieCaptureInstructions.stories.js +23 -23
  97. package/lib/components/selfie/src/selfie-capture-instructions/index.js +3 -3
  98. package/lib/components/selfie/src/selfie-capture-review/SelfieCaptureReview.js +209 -209
  99. package/lib/components/selfie/src/selfie-capture-review/SelfieCaptureReview.stories.js +24 -24
  100. package/lib/components/selfie/src/selfie-capture-review/index.js +3 -3
  101. package/lib/components/selfie/src/selfie-capture-wrapper/SelfieCaptureWrapper.tsx +256 -256
  102. package/lib/components/selfie/src/selfie-capture-wrapper/index.ts +1 -1
  103. package/lib/components/selfie/src/smartselfie-capture/OvalProgress.tsx +81 -81
  104. package/lib/components/selfie/src/smartselfie-capture/SmartSelfieCapture.tsx +265 -265
  105. package/lib/components/selfie/src/smartselfie-capture/components/AlertDisplay.tsx +34 -34
  106. package/lib/components/selfie/src/smartselfie-capture/components/CameraPreview.tsx +97 -97
  107. package/lib/components/selfie/src/smartselfie-capture/components/CaptureControls.tsx +78 -78
  108. package/lib/components/selfie/src/smartselfie-capture/components/index.ts +3 -3
  109. package/lib/components/selfie/src/smartselfie-capture/constants.ts +23 -23
  110. package/lib/components/selfie/src/smartselfie-capture/hooks/index.ts +2 -2
  111. package/lib/components/selfie/src/smartselfie-capture/hooks/useCamera.ts +238 -238
  112. package/lib/components/selfie/src/smartselfie-capture/hooks/useFaceCapture.ts +618 -618
  113. package/lib/components/selfie/src/smartselfie-capture/index.ts +1 -1
  114. package/lib/components/selfie/src/smartselfie-capture/utils/alertMessages.ts +13 -13
  115. package/lib/components/selfie/src/smartselfie-capture/utils/canvas.ts +105 -105
  116. package/lib/components/selfie/src/smartselfie-capture/utils/faceDetection.ts +129 -129
  117. package/lib/components/selfie/src/smartselfie-capture/utils/imageCapture.ts +64 -64
  118. package/lib/components/selfie/src/smartselfie-capture/utils/index.ts +4 -4
  119. package/lib/components/selfie/src/smartselfie-capture/utils/mediapipeManager.ts +77 -77
  120. package/lib/components/signature-pad/package-lock.json +3009 -3009
  121. package/lib/components/signature-pad/package.json +30 -30
  122. package/lib/components/signature-pad/src/SignaturePad.js +484 -484
  123. package/lib/components/signature-pad/src/SignaturePad.stories.js +32 -32
  124. package/lib/components/signature-pad/src/index.js +3 -3
  125. package/lib/components/smart-camera-web/src/README.md +206 -206
  126. package/lib/components/smart-camera-web/src/SmartCameraWeb.js +305 -305
  127. package/lib/components/smart-camera-web/src/SmartCameraWeb.stories.js +57 -57
  128. package/lib/components/totp-consent/src/TotpConsent.js +949 -949
  129. package/lib/components/totp-consent/src/index.js +4 -4
  130. package/lib/domain/camera/src/README.md +38 -38
  131. package/lib/domain/camera/src/SmartCamera.js +109 -109
  132. package/lib/domain/constants/src/Constants.js +27 -27
  133. package/lib/domain/file-upload/README.md +35 -35
  134. package/lib/domain/file-upload/src/SmartFileUpload.js +65 -65
  135. package/lib/styles/README.md +3 -3
  136. package/lib/styles/src/styles.js +372 -372
  137. package/lib/styles/src/typography.js +52 -52
  138. package/package.json +111 -112
  139. package/dist/esm/DocumentCaptureScreens-RECPb0wH.js.map +0 -1
  140. package/dist/esm/SelfieCaptureScreens-CqBVGEJk.js.map +0 -1
  141. package/dist/esm/package-BDJnoIAU.js.map +0 -1
@@ -1,265 +1,265 @@
1
- import { useRef, useEffect } from 'preact/hooks';
2
- import { useSignal } from '@preact/signals';
3
- import register from 'preact-custom-element';
4
- import type { FunctionComponent } from 'preact';
5
- import throttle from 'lodash/throttle';
6
-
7
- import { getBoolProp } from '../../../../utils/props';
8
- import { useFaceCapture, useCamera } from './hooks';
9
- import { CameraPreview } from './components/CameraPreview';
10
- import { AlertDisplay } from './components/AlertDisplay';
11
- import { CaptureControls } from './components/CaptureControls';
12
-
13
- import '../../../navigation/src';
14
- import '../../../attribution/PoweredBySmileId';
15
-
16
- interface Props {
17
- interval?: number;
18
- duration?: number;
19
- 'theme-color'?: string;
20
- 'show-navigation'?: string | boolean;
21
- 'allow-agent-mode'?: string | boolean;
22
- 'show-agent-mode-for-tests'?: string | boolean;
23
- 'hide-attribution'?: string | boolean;
24
- 'disable-image-tests'?: string | boolean;
25
- }
26
-
27
- const SmartSelfieCapture: FunctionComponent<Props> = ({
28
- interval = 350,
29
- duration = 2800,
30
- 'theme-color': themeColor = '#001096',
31
- 'show-navigation': showNavigationProp = false,
32
- 'allow-agent-mode': allowAgentModeProp = false,
33
- 'show-agent-mode-for-tests': showAgentModeForTestsProp = false,
34
- 'hide-attribution': hideAttributionProp = false,
35
- }) => {
36
- const canvasRef = useRef<HTMLCanvasElement>(null);
37
- const navigationRef = useRef<HTMLElement | null>(null);
38
-
39
- const showNavigation = getBoolProp(showNavigationProp);
40
- const allowAgentMode = getBoolProp(allowAgentModeProp);
41
- const showAgentModeForTests = getBoolProp(showAgentModeForTestsProp);
42
- const hideAttribution = getBoolProp(hideAttributionProp);
43
-
44
- const smileCooldown = 300;
45
- const smileThreshold = 0.25;
46
- const mouthOpenThreshold = 0.05;
47
- const minFaceSize = 0.35;
48
- const maxFaceSize = 0.5;
49
-
50
- const initialFacingMode = allowAgentMode ? 'environment' : 'user';
51
- const camera = useCamera(initialFacingMode);
52
-
53
- const throttledMultipleFaces = useSignal(false);
54
- const updateMultipleFacesUI = useRef(
55
- throttle((value: boolean) => {
56
- throttledMultipleFaces.value = value;
57
- }, 100),
58
- ).current;
59
-
60
- const faceCapture = useFaceCapture({
61
- videoRef: camera.videoRef,
62
- canvasRef,
63
- interval,
64
- duration,
65
- smileThreshold,
66
- mouthOpenThreshold,
67
- minFaceSize,
68
- maxFaceSize,
69
- smileCooldown,
70
- getFacingMode: () => camera.facingMode,
71
- });
72
-
73
- useEffect(() => {
74
- const initializeCamera = async () => {
75
- await camera.startCamera(initialFacingMode, (cameraName) => {
76
- const smartCameraWeb = document.querySelector('smart-camera-web');
77
- smartCameraWeb?.dispatchEvent(
78
- new CustomEvent('metadata.camera-name', {
79
- detail: { cameraName },
80
- }),
81
- );
82
- });
83
- await camera.checkAgentSupport();
84
- await faceCapture.initializeFaceLandmarker();
85
-
86
- setTimeout(() => {
87
- faceCapture.setupCanvas();
88
- faceCapture.startDetectionLoop();
89
- }, 500);
90
- };
91
-
92
- camera.registerCameraSwitchCallback(() => {
93
- try {
94
- faceCapture.resetFaceDetectionState();
95
- faceCapture.setupCanvas();
96
- faceCapture.stopDetectionLoop();
97
- faceCapture.startDetectionLoop();
98
- } catch (error) {
99
- console.error('Error during camera switch callback:', error);
100
- }
101
- });
102
-
103
- initializeCamera();
104
-
105
- return () => {
106
- faceCapture.stopDetectionLoop();
107
- camera.stopCamera();
108
- faceCapture.cleanup();
109
- updateMultipleFacesUI.cancel();
110
- };
111
- }, []);
112
-
113
- useEffect(() => {
114
- updateMultipleFacesUI(faceCapture.multipleFaces.value);
115
- }, [faceCapture.multipleFaces.value]);
116
-
117
- useEffect(() => {
118
- const navigation = navigationRef.current;
119
-
120
- if (navigation && showNavigation) {
121
- const handleNavigationBack = () => {
122
- faceCapture.handleCancel();
123
- };
124
-
125
- const handleNavigationClose = () => {
126
- faceCapture.handleClose();
127
- };
128
-
129
- navigation.addEventListener('navigation.back', handleNavigationBack);
130
- navigation.addEventListener('navigation.close', handleNavigationClose);
131
-
132
- return () => {
133
- navigation.removeEventListener('navigation.back', handleNavigationBack);
134
- navigation.removeEventListener(
135
- 'navigation.close',
136
- handleNavigationClose,
137
- );
138
- };
139
- }
140
- return undefined;
141
- }, [showNavigation]);
142
-
143
- useEffect(() => {
144
- if (faceCapture.hasFinishedCapture.value) {
145
- const smartCameraWeb = document.querySelector('smart-camera-web');
146
- smartCameraWeb?.dispatchEvent(
147
- new CustomEvent('metadata.selfie-capture-end'),
148
- );
149
- }
150
- }, [faceCapture.hasFinishedCapture.value]);
151
-
152
- return (
153
- <div className="smartselfie-capture">
154
- {showNavigation && (
155
- // @ts-ignore
156
- <smileid-navigation ref={navigationRef} theme-color={themeColor} />
157
- )}
158
-
159
- <CameraPreview
160
- videoRef={camera.videoRef}
161
- canvasRef={canvasRef}
162
- facingMode={camera.facingMode}
163
- multipleFaces={throttledMultipleFaces.value}
164
- progress={
165
- faceCapture.capturesTaken.value > 0
166
- ? faceCapture.capturesTaken.value / faceCapture.totalCaptures.value
167
- : 0
168
- }
169
- interval={interval}
170
- themeColor={themeColor}
171
- />
172
-
173
- <AlertDisplay alertTitle={faceCapture.alertTitle.value} />
174
-
175
- {!faceCapture.isCapturing.value &&
176
- !faceCapture.hasFinishedCapture.value && (
177
- <CaptureControls
178
- isCapturing={faceCapture.isCapturing.value}
179
- hasFinishedCapture={faceCapture.hasFinishedCapture.value}
180
- isReadyToCapture={faceCapture.isReadyToCapture.value}
181
- allowAgentMode={allowAgentMode}
182
- agentSupported={camera.agentSupported}
183
- showAgentModeForTests={showAgentModeForTests}
184
- facingMode={camera.facingMode}
185
- themeColor={themeColor}
186
- onStartCapture={faceCapture.startCapture}
187
- onSwitchCamera={camera.switchCamera}
188
- />
189
- )}
190
-
191
- {/* @ts-ignore */}
192
- {!hideAttribution && <powered-by-smile-id />}
193
-
194
- <style>{`
195
- * {
196
- box-sizing: border-box;
197
- }
198
-
199
- button {
200
- padding: 10px 20px;
201
- background: ${themeColor || '#001096'};
202
- color: white;
203
- border: none;
204
- border-radius: 4px;
205
- cursor: pointer;
206
- font-size: 16px;
207
- }
208
-
209
- button:disabled {
210
- background: #ccc;
211
- cursor: not-allowed;
212
- }
213
-
214
- button.btn-primary {
215
- background-color: ${themeColor || '#001096'};
216
- border-radius: 2.5rem;
217
- color: white;
218
- border: none;
219
- height: 3.125rem;
220
- display: inline-block;
221
- padding: 0.75rem 1.5rem;
222
- text-align: center;
223
- font-size: 1.125rem;
224
- font-weight: 600;
225
- font-family: "DM Sans", sans-serif;
226
- cursor: pointer;
227
- }
228
-
229
- button.btn-primary:hover {
230
- background-color: #2d2b2a;
231
- }
232
-
233
- button.btn-primary:disabled {
234
- background-color: #666;
235
- cursor: not-allowed;
236
- }
237
-
238
- .smartselfie-capture {
239
- padding: 1rem;
240
- font-family: sans-serif;
241
- }
242
- `}</style>
243
- </div>
244
- );
245
- };
246
-
247
- if (!customElements.get('smartselfie-capture')) {
248
- register(
249
- SmartSelfieCapture,
250
- 'smartselfie-capture',
251
- [
252
- 'interval',
253
- 'duration',
254
- 'theme-color',
255
- 'show-navigation',
256
- 'allow-agent-mode',
257
- 'show-agent-mode-for-tests',
258
- 'hide-attribution',
259
- 'disable-image-tests',
260
- ],
261
- { shadow: true },
262
- );
263
- }
264
-
265
- export default SmartSelfieCapture;
1
+ import { useRef, useEffect } from 'preact/hooks';
2
+ import { useSignal } from '@preact/signals';
3
+ import register from 'preact-custom-element';
4
+ import type { FunctionComponent } from 'preact';
5
+ import throttle from 'lodash/throttle';
6
+
7
+ import { getBoolProp } from '../../../../utils/props';
8
+ import { useFaceCapture, useCamera } from './hooks';
9
+ import { CameraPreview } from './components/CameraPreview';
10
+ import { AlertDisplay } from './components/AlertDisplay';
11
+ import { CaptureControls } from './components/CaptureControls';
12
+
13
+ import '../../../navigation/src';
14
+ import '../../../attribution/PoweredBySmileId';
15
+
16
+ interface Props {
17
+ interval?: number;
18
+ duration?: number;
19
+ 'theme-color'?: string;
20
+ 'show-navigation'?: string | boolean;
21
+ 'allow-agent-mode'?: string | boolean;
22
+ 'show-agent-mode-for-tests'?: string | boolean;
23
+ 'hide-attribution'?: string | boolean;
24
+ 'disable-image-tests'?: string | boolean;
25
+ }
26
+
27
+ const SmartSelfieCapture: FunctionComponent<Props> = ({
28
+ interval = 350,
29
+ duration = 2800,
30
+ 'theme-color': themeColor = '#001096',
31
+ 'show-navigation': showNavigationProp = false,
32
+ 'allow-agent-mode': allowAgentModeProp = false,
33
+ 'show-agent-mode-for-tests': showAgentModeForTestsProp = false,
34
+ 'hide-attribution': hideAttributionProp = false,
35
+ }) => {
36
+ const canvasRef = useRef<HTMLCanvasElement>(null);
37
+ const navigationRef = useRef<HTMLElement | null>(null);
38
+
39
+ const showNavigation = getBoolProp(showNavigationProp);
40
+ const allowAgentMode = getBoolProp(allowAgentModeProp);
41
+ const showAgentModeForTests = getBoolProp(showAgentModeForTestsProp);
42
+ const hideAttribution = getBoolProp(hideAttributionProp);
43
+
44
+ const smileCooldown = 300;
45
+ const smileThreshold = 0.25;
46
+ const mouthOpenThreshold = 0.05;
47
+ const minFaceSize = 0.35;
48
+ const maxFaceSize = 0.5;
49
+
50
+ const initialFacingMode = allowAgentMode ? 'environment' : 'user';
51
+ const camera = useCamera(initialFacingMode);
52
+
53
+ const throttledMultipleFaces = useSignal(false);
54
+ const updateMultipleFacesUI = useRef(
55
+ throttle((value: boolean) => {
56
+ throttledMultipleFaces.value = value;
57
+ }, 100),
58
+ ).current;
59
+
60
+ const faceCapture = useFaceCapture({
61
+ videoRef: camera.videoRef,
62
+ canvasRef,
63
+ interval,
64
+ duration,
65
+ smileThreshold,
66
+ mouthOpenThreshold,
67
+ minFaceSize,
68
+ maxFaceSize,
69
+ smileCooldown,
70
+ getFacingMode: () => camera.facingMode,
71
+ });
72
+
73
+ useEffect(() => {
74
+ const initializeCamera = async () => {
75
+ await camera.startCamera(initialFacingMode, (cameraName) => {
76
+ const smartCameraWeb = document.querySelector('smart-camera-web');
77
+ smartCameraWeb?.dispatchEvent(
78
+ new CustomEvent('metadata.camera-name', {
79
+ detail: { cameraName },
80
+ }),
81
+ );
82
+ });
83
+ await camera.checkAgentSupport();
84
+ await faceCapture.initializeFaceLandmarker();
85
+
86
+ setTimeout(() => {
87
+ faceCapture.setupCanvas();
88
+ faceCapture.startDetectionLoop();
89
+ }, 500);
90
+ };
91
+
92
+ camera.registerCameraSwitchCallback(() => {
93
+ try {
94
+ faceCapture.resetFaceDetectionState();
95
+ faceCapture.setupCanvas();
96
+ faceCapture.stopDetectionLoop();
97
+ faceCapture.startDetectionLoop();
98
+ } catch (error) {
99
+ console.error('Error during camera switch callback:', error);
100
+ }
101
+ });
102
+
103
+ initializeCamera();
104
+
105
+ return () => {
106
+ faceCapture.stopDetectionLoop();
107
+ camera.stopCamera();
108
+ faceCapture.cleanup();
109
+ updateMultipleFacesUI.cancel();
110
+ };
111
+ }, []);
112
+
113
+ useEffect(() => {
114
+ updateMultipleFacesUI(faceCapture.multipleFaces.value);
115
+ }, [faceCapture.multipleFaces.value]);
116
+
117
+ useEffect(() => {
118
+ const navigation = navigationRef.current;
119
+
120
+ if (navigation && showNavigation) {
121
+ const handleNavigationBack = () => {
122
+ faceCapture.handleCancel();
123
+ };
124
+
125
+ const handleNavigationClose = () => {
126
+ faceCapture.handleClose();
127
+ };
128
+
129
+ navigation.addEventListener('navigation.back', handleNavigationBack);
130
+ navigation.addEventListener('navigation.close', handleNavigationClose);
131
+
132
+ return () => {
133
+ navigation.removeEventListener('navigation.back', handleNavigationBack);
134
+ navigation.removeEventListener(
135
+ 'navigation.close',
136
+ handleNavigationClose,
137
+ );
138
+ };
139
+ }
140
+ return undefined;
141
+ }, [showNavigation]);
142
+
143
+ useEffect(() => {
144
+ if (faceCapture.hasFinishedCapture.value) {
145
+ const smartCameraWeb = document.querySelector('smart-camera-web');
146
+ smartCameraWeb?.dispatchEvent(
147
+ new CustomEvent('metadata.selfie-capture-end'),
148
+ );
149
+ }
150
+ }, [faceCapture.hasFinishedCapture.value]);
151
+
152
+ return (
153
+ <div className="smartselfie-capture">
154
+ {showNavigation && (
155
+ // @ts-ignore
156
+ <smileid-navigation ref={navigationRef} theme-color={themeColor} />
157
+ )}
158
+
159
+ <CameraPreview
160
+ videoRef={camera.videoRef}
161
+ canvasRef={canvasRef}
162
+ facingMode={camera.facingMode}
163
+ multipleFaces={throttledMultipleFaces.value}
164
+ progress={
165
+ faceCapture.capturesTaken.value > 0
166
+ ? faceCapture.capturesTaken.value / faceCapture.totalCaptures.value
167
+ : 0
168
+ }
169
+ interval={interval}
170
+ themeColor={themeColor}
171
+ />
172
+
173
+ <AlertDisplay alertTitle={faceCapture.alertTitle.value} />
174
+
175
+ {!faceCapture.isCapturing.value &&
176
+ !faceCapture.hasFinishedCapture.value && (
177
+ <CaptureControls
178
+ isCapturing={faceCapture.isCapturing.value}
179
+ hasFinishedCapture={faceCapture.hasFinishedCapture.value}
180
+ isReadyToCapture={faceCapture.isReadyToCapture.value}
181
+ allowAgentMode={allowAgentMode}
182
+ agentSupported={camera.agentSupported}
183
+ showAgentModeForTests={showAgentModeForTests}
184
+ facingMode={camera.facingMode}
185
+ themeColor={themeColor}
186
+ onStartCapture={faceCapture.startCapture}
187
+ onSwitchCamera={camera.switchCamera}
188
+ />
189
+ )}
190
+
191
+ {/* @ts-ignore */}
192
+ {!hideAttribution && <powered-by-smile-id />}
193
+
194
+ <style>{`
195
+ * {
196
+ box-sizing: border-box;
197
+ }
198
+
199
+ button {
200
+ padding: 10px 20px;
201
+ background: ${themeColor || '#001096'};
202
+ color: white;
203
+ border: none;
204
+ border-radius: 4px;
205
+ cursor: pointer;
206
+ font-size: 16px;
207
+ }
208
+
209
+ button:disabled {
210
+ background: #ccc;
211
+ cursor: not-allowed;
212
+ }
213
+
214
+ button.btn-primary {
215
+ background-color: ${themeColor || '#001096'};
216
+ border-radius: 2.5rem;
217
+ color: white;
218
+ border: none;
219
+ height: 3.125rem;
220
+ display: inline-block;
221
+ padding: 0.75rem 1.5rem;
222
+ text-align: center;
223
+ font-size: 1.125rem;
224
+ font-weight: 600;
225
+ font-family: "DM Sans", sans-serif;
226
+ cursor: pointer;
227
+ }
228
+
229
+ button.btn-primary:hover {
230
+ background-color: #2d2b2a;
231
+ }
232
+
233
+ button.btn-primary:disabled {
234
+ background-color: #666;
235
+ cursor: not-allowed;
236
+ }
237
+
238
+ .smartselfie-capture {
239
+ padding: 1rem;
240
+ font-family: sans-serif;
241
+ }
242
+ `}</style>
243
+ </div>
244
+ );
245
+ };
246
+
247
+ if (!customElements.get('smartselfie-capture')) {
248
+ register(
249
+ SmartSelfieCapture,
250
+ 'smartselfie-capture',
251
+ [
252
+ 'interval',
253
+ 'duration',
254
+ 'theme-color',
255
+ 'show-navigation',
256
+ 'allow-agent-mode',
257
+ 'show-agent-mode-for-tests',
258
+ 'hide-attribution',
259
+ 'disable-image-tests',
260
+ ],
261
+ { shadow: true },
262
+ );
263
+ }
264
+
265
+ export default SmartSelfieCapture;
@@ -1,34 +1,34 @@
1
- import type { FunctionComponent } from 'preact';
2
-
3
- interface AlertDisplayProps {
4
- alertTitle: string;
5
- }
6
-
7
- export const AlertDisplay: FunctionComponent<AlertDisplayProps> = ({
8
- alertTitle,
9
- }) =>
10
- alertTitle ? (
11
- <>
12
- <div className="alert-message">
13
- <div className="alert-title">{alertTitle}</div>
14
- </div>
15
-
16
- <style>{`
17
- .alert-message {
18
- margin-top: 1.5rem;
19
- color: #000;
20
- color: #151F72;
21
- padding: 0.5rem 1.5rem;
22
- border-radius: 4px;
23
- text-align: start;
24
- width: 100%;
25
- }
26
-
27
- .alert-title {
28
- font-size: 16px;
29
- font-weight: bold;
30
- text-align: center;
31
- }
32
- `}</style>
33
- </>
34
- ) : null;
1
+ import type { FunctionComponent } from 'preact';
2
+
3
+ interface AlertDisplayProps {
4
+ alertTitle: string;
5
+ }
6
+
7
+ export const AlertDisplay: FunctionComponent<AlertDisplayProps> = ({
8
+ alertTitle,
9
+ }) =>
10
+ alertTitle ? (
11
+ <>
12
+ <div className="alert-message">
13
+ <div className="alert-title">{alertTitle}</div>
14
+ </div>
15
+
16
+ <style>{`
17
+ .alert-message {
18
+ margin-top: 1.5rem;
19
+ color: #000;
20
+ color: #151F72;
21
+ padding: 0.5rem 1.5rem;
22
+ border-radius: 4px;
23
+ text-align: start;
24
+ width: 100%;
25
+ }
26
+
27
+ .alert-title {
28
+ font-size: 16px;
29
+ font-weight: bold;
30
+ text-align: center;
31
+ }
32
+ `}</style>
33
+ </>
34
+ ) : null;