@smileid/web-components 11.5.0 → 11.6.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 (82) hide show
  1. package/dist/esm/DocumentCaptureScreens-DjSTdVP-.js +5398 -0
  2. package/dist/esm/DocumentCaptureScreens-DjSTdVP-.js.map +1 -0
  3. package/dist/esm/{Navigation-Xg565kcu.js → Navigation-6DH3vF4-.js} +2 -2
  4. package/dist/esm/{Navigation-Xg565kcu.js.map → Navigation-6DH3vF4-.js.map} +1 -1
  5. package/dist/esm/{PoweredBySmileId-CxbaihMu.js → PoweredBySmileId-DoKwoPUd.js} +424 -6
  6. package/dist/esm/PoweredBySmileId-DoKwoPUd.js.map +1 -0
  7. package/dist/esm/{SelfieCaptureScreens-D3KuMzZA.js → SelfieCaptureScreens-CtX-4Tco.js} +5 -6
  8. package/dist/esm/SelfieCaptureScreens-CtX-4Tco.js.map +1 -0
  9. package/dist/esm/combobox.js +1 -1
  10. package/dist/esm/document.js +1 -1
  11. package/dist/esm/end-user-consent.js +713 -2
  12. package/dist/esm/end-user-consent.js.map +1 -1
  13. package/dist/esm/index-BqyuTk9f.js +1366 -0
  14. package/dist/esm/{index-CUwa6MPI.js.map → index-BqyuTk9f.js.map} +1 -1
  15. package/dist/esm/localisation.js +1 -1
  16. package/dist/esm/main.js +14 -14
  17. package/dist/esm/navigation.js +1 -1
  18. package/dist/esm/{package-BmVbDNny.js → package-CjZI-cNQ.js} +177 -172
  19. package/dist/esm/{package-BmVbDNny.js.map → package-CjZI-cNQ.js.map} +1 -1
  20. package/dist/esm/selfie.js +1 -1
  21. package/dist/esm/smart-camera-web.js +32 -18
  22. package/dist/esm/smart-camera-web.js.map +1 -1
  23. package/dist/esm/totp-consent.js +731 -2
  24. package/dist/esm/totp-consent.js.map +1 -1
  25. package/dist/esm/validate.js +31 -0
  26. package/dist/esm/validate.js.map +1 -0
  27. package/dist/smart-camera-web.js +696 -321
  28. package/dist/smart-camera-web.js.map +1 -1
  29. package/dist/types/main.d.ts +7 -1
  30. package/dist/types/validate.d.ts +21 -0
  31. package/lib/components/document/src/DocumentCaptureScreens.js +97 -18
  32. package/lib/components/document/src/assets/lottie.d.ts +12 -0
  33. package/lib/components/document/src/assets/svg-inline.d.ts +8 -0
  34. package/lib/components/document/src/document-auto-capture/DocumentAutoCapture.stories.js +75 -0
  35. package/lib/components/document/src/document-auto-capture/DocumentAutoCapture.tsx +1458 -0
  36. package/lib/components/document/src/document-auto-capture/README.md +73 -0
  37. package/lib/components/document/src/document-auto-capture/assets/Greenbook_Shimmer.svg +42 -0
  38. package/lib/components/document/src/document-auto-capture/assets/ID_Back_Shimmer.svg +8 -0
  39. package/lib/components/document/src/document-auto-capture/assets/ID_Front_Shimmer.svg +20 -0
  40. package/lib/components/document/src/document-auto-capture/assets/Passport-Shimmer.svg +143 -0
  41. package/lib/components/document/src/document-auto-capture/assets/shimmers.ts +21 -0
  42. package/lib/components/document/src/document-auto-capture/assets/svg-raw.d.ts +4 -0
  43. package/lib/components/document/src/document-auto-capture/components/CaptureButton.tsx +122 -0
  44. package/lib/components/document/src/document-auto-capture/components/Overlay.tsx +167 -0
  45. package/lib/components/document/src/document-auto-capture/components/TuningPanel.tsx +856 -0
  46. package/lib/components/document/src/document-auto-capture/constants/captureLayout.ts +58 -0
  47. package/lib/components/document/src/document-auto-capture/detection/cvErrorRecovery.ts +40 -0
  48. package/lib/components/document/src/document-auto-capture/detection/documentAspect.ts +20 -0
  49. package/lib/components/document/src/document-auto-capture/detection/qualityScoring.ts +35 -0
  50. package/lib/components/document/src/document-auto-capture/detection/seamRejection.ts +209 -0
  51. package/lib/components/document/src/document-auto-capture/detection/synthesisTiming.ts +10 -0
  52. package/lib/components/document/src/document-auto-capture/hooks/useCamera.ts +117 -0
  53. package/lib/components/document/src/document-auto-capture/hooks/useCardDetection.ts +3059 -0
  54. package/lib/components/document/src/document-auto-capture/index.ts +4 -0
  55. package/lib/components/document/src/document-auto-capture/theme.ts +40 -0
  56. package/lib/components/document/src/document-auto-capture/utils/debug.ts +25 -0
  57. package/lib/components/document/src/document-auto-capture/utils/opencvLoader.ts +86 -0
  58. package/lib/components/document/src/document-capture-instructions/DocumentCaptureInstructions.tsx +327 -244
  59. package/lib/components/document/src/document-capture-review/DocumentCaptureReview.js +153 -189
  60. package/lib/components/document/src/document-capture-submission/DocumentCaptureSubmission.tsx +432 -0
  61. package/lib/components/document/src/document-capture-submission/index.js +3 -0
  62. package/lib/components/selfie/README.md +13 -0
  63. package/lib/components/signature-pad/package.json +1 -1
  64. package/lib/components/smart-camera-web/src/README.md +11 -0
  65. package/lib/components/smart-camera-web/src/SmartCameraWeb.js +25 -1
  66. package/lib/components/totp-consent/src/TotpConsent.js +1 -1
  67. package/package.json +8 -4
  68. package/dist/esm/DocumentCaptureScreens-ucJDu5nH.js +0 -2232
  69. package/dist/esm/DocumentCaptureScreens-ucJDu5nH.js.map +0 -1
  70. package/dist/esm/EndUserConsent-CsiwoThZ.js +0 -717
  71. package/dist/esm/EndUserConsent-CsiwoThZ.js.map +0 -1
  72. package/dist/esm/PoweredBySmileId-CxbaihMu.js.map +0 -1
  73. package/dist/esm/SelfieCaptureScreens-D3KuMzZA.js.map +0 -1
  74. package/dist/esm/TotpConsent-CRtmtudl.js +0 -734
  75. package/dist/esm/TotpConsent-CRtmtudl.js.map +0 -1
  76. package/dist/esm/index-CUwa6MPI.js +0 -1363
  77. package/dist/esm/styles-BTEClL7R.js +0 -419
  78. package/dist/esm/styles-BTEClL7R.js.map +0 -1
  79. /package/lib/components/document/src/assets/lottie/{taking photo of green book passport.lottie → greenbook.lottie} +0 -0
  80. /package/lib/components/document/src/assets/lottie/{taking photo of ID FLIP 2D.lottie → id-card-flip.lottie} +0 -0
  81. /package/lib/components/document/src/assets/lottie/{taking photo of ID.lottie → id-card.lottie} +0 -0
  82. /package/lib/components/document/src/assets/lottie/{taking photo of passport 2.lottie → passport.lottie} +0 -0
@@ -5,249 +5,214 @@ import { t, getDirection } from '../../../../domain/localisation';
5
5
  function templateString() {
6
6
  return `
7
7
  <style>
8
- .retake-photo.button[data-variant~="ghost"] {
9
- color: #FF5805;
8
+ :host {
9
+ display: block;
10
+ width: 100%;
11
+ height: 100%;
10
12
  }
11
13
 
12
-
13
- @media (max-width: 600px) {
14
- .id-camera-screen {
15
- width: 100%;
16
- height: 100vh;
17
- }
18
-
19
- .section {
20
- width: 100%;
21
- justify-content: center;
22
- }
14
+ *, *::before, *::after {
15
+ box-sizing: border-box;
23
16
  }
24
-
25
- .id-image-container {
17
+
18
+ #document-capture-review-screen {
19
+ font-family: 'DM Sans', system-ui, -apple-system, sans-serif;
20
+ background: #f8fafc;
26
21
  display: flex;
27
22
  flex-direction: column;
28
- align-items: center;
29
- gap: 1.75rem;
30
- }
31
-
32
- .id-image {
33
- width: 100%;
34
- text-align: center;
35
- position: relative;
36
- background: white;
37
- }
38
- img {
23
+ width: 100%;
39
24
  height: 100%;
40
- min-height: 100px;
41
- width: 98%;
25
+ min-height: 100%;
26
+ position: relative;
27
+ overflow: hidden;
42
28
  }
43
29
 
44
- .action-buttons {
45
- width: 80%;
30
+ /* ── Navigation (top) ─────────────────────────────────── */
31
+ .review-nav {
32
+ position: absolute;
33
+ top: 16px;
34
+ left: 16px;
35
+ right: 16px;
36
+ z-index: 10;
46
37
  }
47
38
 
48
-
49
- .icon-btn {
50
- appearance: none;
51
- background: none;
52
- border: none;
53
- color: hsl(0deg 0% 94%);
54
- cursor: pointer;
39
+ /* ── Captured image area ──────────────────────────────── */
40
+ .review-image-area {
41
+ flex: 1;
55
42
  display: flex;
56
43
  align-items: center;
57
44
  justify-content: center;
58
- padding: 4px 8px;
59
- }
60
- .justify-right {
61
- justify-content: end !important;
62
- }
63
- .nav {
64
- display: flex;
65
- justify-content: space-between;
45
+ padding: 72px 24px 16px;
46
+ min-height: 0;
66
47
  }
67
48
 
68
- .back-wrapper {
69
- display: flex;
70
- align-items: center;
71
- }
72
-
73
- .back-button-text {
74
- font-size: 11px;
75
- line-height: 11px;
76
- color: rgb(21, 31, 114);
49
+ .review-image {
50
+ max-width: 100%;
51
+ max-height: 100%;
52
+ width: auto;
53
+ height: auto;
54
+ border-radius: 12px;
55
+ display: block;
56
+ object-fit: contain;
77
57
  }
78
58
 
79
-
80
-
81
- .tips,
82
- .powered-by {
83
- align-items: center;
84
- border-radius: 0.25rem;
85
- color: #4e6577;
59
+ /* ── Bottom card ──────────────────────────────────────── */
60
+ .review-footer {
61
+ padding: 0 20px 16px;
86
62
  display: flex;
87
- justify-content: center;
88
- letter-spacing: 0.075em;
89
- }
90
-
91
- .powered-by {
92
- box-shadow: 0px 2.57415px 2.57415px rgba(0, 0, 0, 0.06);
93
- display: inline-flex;
94
- font-size: 0.5rem;
95
- }
96
-
97
- .tips {
98
- margin-left: auto;
99
- margin-right: auto;
100
- max-width: 17rem;
101
- }
102
-
103
- .tips > * + *,
104
- .powered-by > * + * {
105
- display: inline-block;
106
- margin-left: 0.5em;
107
- }
108
-
109
- .powered-by .company {
110
- color: #18406d;
111
- font-weight: 700;
112
- letter-spacing: 0.15rem;
113
- }
114
-
115
- .logo-mark {
116
- background-color: #004071;
117
- display: inline-block;
118
- padding: 0.25em 0.5em;
63
+ flex-direction: column;
64
+ align-items: center;
65
+ gap: 16px;
66
+ flex-shrink: 0;
119
67
  }
120
68
 
121
- .logo-mark svg {
122
- height: auto;
123
- justify-self: center;
124
- width: 0.75em;
125
- }
126
-
127
- #document-capture-review-screen {
69
+ .review-card {
70
+ width: 100%;
71
+ max-width: 420px;
72
+ background: #ffffff;
73
+ border-radius: 16px;
74
+ box-shadow: 0px 12px 16px -4px rgba(16, 24, 40, 0.08),
75
+ 0px 4px 6px -2px rgba(16, 24, 40, 0.03);
76
+ padding: 24px 20px;
128
77
  display: flex;
129
78
  flex-direction: column;
130
- max-block-size: 100%;
131
- max-inline-size: 40ch;
132
- padding: 1rem;
133
- }
134
-
135
- #document-capture-review-screen .id-image-container.landscape {
136
- height: auto;
79
+ align-items: center;
80
+ gap: 4px;
81
+ text-align: center;
137
82
  }
138
83
 
139
- #document-capture-review-screen header p {
140
- margin-block: 0 !important;
84
+ .review-title {
85
+ margin: 0;
86
+ font-size: 1.125rem;
87
+ font-weight: 700;
88
+ color: ${this.themeColor};
141
89
  }
142
90
 
143
- .description {
144
- color: var(--neutral-off-black, #2D2B2A);
145
- text-align: center;
146
-
147
- /* p */
148
- font-family: DM Sans;
149
- font-size: 0.875rem;
150
- font-style: normal;
91
+ .review-description {
92
+ margin: 0 0 8px;
93
+ font-size: 0.8125rem;
151
94
  font-weight: 400;
152
- line-height: 18px;
95
+ line-height: 1.3;
96
+ color: #5b6b7b;
153
97
  }
154
98
 
155
- .padding-bottom-2 {
156
- padding-bottom: 2rem;
99
+ /* ── Circular action buttons ──────────────────────────── */
100
+ .review-actions {
101
+ display: flex;
102
+ gap: 40px;
103
+ align-items: flex-start;
104
+ justify-content: center;
105
+ margin-top: 4px;
157
106
  }
158
- img {
159
- border-width: 0.25rem;
160
- border-color: #9394ab;
161
- border-style: solid;
162
- border-radius: 0.25rem;
163
- }
164
107
 
165
- .instructions-wrapper {
166
- display: inline-flex;
108
+ .circle-btn {
109
+ appearance: none;
110
+ background: none;
111
+ border: none;
112
+ padding: 0;
113
+ cursor: pointer;
114
+ display: flex;
167
115
  flex-direction: column;
168
- align-items: flex-start;
169
- gap: 2rem;
170
- margin-block-start: 2rem;
171
- margin-block-end: 4rem;
116
+ align-items: center;
117
+ gap: 8px;
172
118
  }
173
- .instructions {
119
+
120
+ .circle {
121
+ width: 56px;
122
+ height: 56px;
123
+ border-radius: 50%;
174
124
  display: flex;
175
125
  align-items: center;
176
- text-align: initial;
126
+ justify-content: center;
127
+ transition: transform 0.1s ease, opacity 0.15s ease;
177
128
  }
178
129
 
179
- .instructions svg {
180
- flex-shrink: 0;
181
- margin-inline-end: 2rem;
130
+ .circle-btn:active .circle {
131
+ transform: scale(0.95);
182
132
  }
183
133
 
184
- .instructions p {
185
- margin-block: 0;
134
+ .circle-btn.retake .circle {
135
+ background: #ffffff;
136
+ border: 1.5px solid #cbd5e1;
186
137
  }
187
138
 
188
- .instruction-body {
189
- font-size: 0.75rem;
139
+ .circle-btn.confirm .circle {
140
+ background: #e7f9ee;
141
+ border: 1.5px solid #2cc05c;
190
142
  }
191
143
 
192
- h1 {
193
- color: var(--web-digital-blue, #001096);
194
- text-align: center;
144
+ .circle-label {
145
+ font-size: 0.75rem;
146
+ font-weight: 500;
147
+ color: #90a1b9;
148
+ }
195
149
 
196
- /* h1 */
197
- font-size: 1.25rem;
198
- font-style: normal;
199
- font-weight: 700;
200
- line-height: 36px; /* 150% */
150
+ .circle-label.confirm-label {
151
+ color: #12b76a;
201
152
  }
202
153
 
203
- .p2 {
204
- font-size: 1rem;
205
- font-style: normal;
206
- font-weight: 500;
207
- line-height: 1rem;
154
+ .circle-btn:focus-visible {
155
+ outline: 2px solid ${this.themeColor};
156
+ outline-offset: 3px;
157
+ border-radius: 8px;
208
158
  }
209
159
 
210
- .instruction-header {
211
- color: var(--web-digital-blue, #001096);
160
+ .review-attribution {
161
+ display: flex;
162
+ align-items: center;
163
+ justify-content: center;
212
164
  }
213
165
 
214
- .h2 {
215
- font-size: 1rem;
216
- font-style: normal;
217
- font-weight: 700;
218
- line-height: 1.5rem;
166
+ @media (min-width: 640px) {
167
+ .review-image-area {
168
+ padding-top: 80px;
169
+ }
170
+ .review-close {
171
+ top: 28px;
172
+ right: 28px;
173
+ }
219
174
  }
220
175
  </style>
221
176
  ${styles(this.themeColor)}
222
- <div id='document-capture-review-screen' class='flow center' dir='${this.direction}'>
223
- ${this.showNavigation ? `<smileid-navigation show-navigation hide-back></smileid-navigation>` : ''}
224
- <h1 class="header-title title-color">
225
- ${t('document.review.question')}
226
- </h1>
227
- <p class="description">${t('document.review.description')}</p>
228
- <div class='section | flow'>
229
- <div class='id-image-container'>
230
- <div class='id-image'>
231
- <div class='video-overlay'></div>
232
- ${this.imageSrc ? `<img alt='your ID card' id='document-capture-review-image' src='${this.imageSrc}' />` : ''}
233
- </div>
234
- <div class='flow action-buttons'>
235
- <button data-variant='solid full-width' class='button' type='button' id='select-id-image'>
236
- ${t('document.review.acceptButton')}
177
+ <div id='document-capture-review-screen' dir='${this.direction}'>
178
+ ${
179
+ this.showNavigation
180
+ ? `<div class='review-nav'>
181
+ <smileid-navigation theme-color='${this.themeColor}' show-navigation hide-back></smileid-navigation>
182
+ </div>`
183
+ : ''
184
+ }
185
+
186
+ <div class='review-image-area'>
187
+ ${this.imageSrc ? `<img class='review-image' alt='${t('document.submission.imageAlt')}' id='document-capture-review-image' src='${this.imageSrc.replace(/'/g, '&#39;').replace(/</g, '&lt;')}' />` : ''}
188
+ </div>
189
+
190
+ <div class='review-footer'>
191
+ <div class='review-card'>
192
+ <h1 class='review-title'>${t('document.review.confirmTitle')}</h1>
193
+ <p class='review-description'>${t('document.review.confirmBody')}</p>
194
+ <div class='review-actions'>
195
+ <button class='circle-btn retake' type='button' id='re-capture-id-image' aria-label='${t('document.review.retake')}'>
196
+ <span class='circle'>
197
+ <svg width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='#90A1B9' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' aria-hidden='true'>
198
+ <polyline points='1 4 1 10 7 10'></polyline>
199
+ <path d='M3.51 15a9 9 0 1 0 2.13-9.36L1 10'></path>
200
+ </svg>
201
+ </span>
202
+ <span class='circle-label'>${t('document.review.retake')}</span>
237
203
  </button>
238
- <button data-variant='ghost full-width' class='button retake-photo' type='button' id='re-capture-id-image'>
239
- ${t('document.review.retakeButton')}
204
+ <button class='circle-btn confirm' type='button' id='select-id-image' aria-label='${t('document.review.confirm')}'>
205
+ <span class='circle'>
206
+ <svg width='26' height='26' viewBox='0 0 24 24' fill='none' stroke='#12B76A' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round' aria-hidden='true'>
207
+ <polyline points='20 6 9 17 4 12'></polyline>
208
+ </svg>
209
+ </span>
210
+ <span class='circle-label confirm-label'>${t('document.review.confirm')}</span>
240
211
  </button>
241
212
  </div>
242
213
  </div>
243
214
 
244
- ${
245
- this.hideAttribution
246
- ? ''
247
- : `
248
- <powered-by-smile-id></powered-by-smile-id>
249
- `
250
- }
215
+ ${this.hideAttribution ? '' : '<div class="review-attribution"><powered-by-smile-id></powered-by-smile-id></div>'}
251
216
  </div>
252
217
  </div>
253
218
  `;
@@ -329,13 +294,12 @@ class IdReview extends HTMLElement {
329
294
  '#re-capture-id-image',
330
295
  );
331
296
  this.navigation = this.shadowRoot.querySelector('smileid-navigation');
332
- this.navigation?.addEventListener('navigation.back', () => {
333
- this.handleBackEvents();
334
- });
335
-
336
297
  this.navigation?.addEventListener('navigation.close', () => {
337
298
  this.handleCloseEvents();
338
299
  });
300
+ this.navigation?.addEventListener('navigation.back', () => {
301
+ this.handleBackEvents();
302
+ });
339
303
 
340
304
  this.selectIDImage.addEventListener('click', () => {
341
305
  this.dispatchEvent(