@smileid/web-components 1.4.3 → 1.4.5-alpha.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.
@@ -5,7 +5,9 @@ import SmartCamera from '../../../domain/camera/src/SmartCamera';
5
5
  import './document-capture';
6
6
  import './document-capture-review';
7
7
  import './document-capture-instructions';
8
- import { version as COMPONENTS_VERSION } from '../../../package.json';
8
+ import packageJson from '../../../package.json';
9
+
10
+ const COMPONENTS_VERSION = packageJson.version;
9
11
 
10
12
  async function getPermissions(captureScreen) {
11
13
  try {
@@ -34,20 +36,23 @@ class DocumentCaptureScreens extends HTMLElement {
34
36
  this.innerHTML = `
35
37
  ${styles(this.themeColor)}
36
38
  <div>
37
- <document-capture-instructions theme-color='${this.themeColor}' id='document-capture-instructions-front' ${this.title} ${this.documentCaptureModes} ${this.showNavigation} ${this.hideInstructions ? 'hidden' : ''}></document-capture-instructions>
39
+ <document-capture-instructions theme-color='${this.themeColor}' id='document-capture-instructions-front' ${this.title}
40
+ ${this.documentCaptureModes} ${this.showNavigation} ${this.hideInstructions ? 'hidden' : ''}
41
+ ${this.hideAttribution}
42
+ ></document-capture-instructions>
38
43
  <document-capture id='document-capture-front' side-of-id='Front'
39
- ${this.title} ${this.showNavigation} ${this.hideInstructions ? '' : 'hidden'}
44
+ ${this.title} ${this.showNavigation} ${this.hideInstructions ? '' : 'hidden'} ${this.hideAttribution}
40
45
  ${this.documentCaptureModes} ${this.documentType} theme-color='${this.themeColor}'
41
46
  ></document-capture>
42
47
  <document-capture-instructions id='document-capture-instructions-back' side-of-id='Back' title='Submit Back of ID'
43
- ${this.documentCaptureModes} ${this.showNavigation} theme-color='${this.themeColor}' hidden
48
+ ${this.documentCaptureModes} ${this.showNavigation} theme-color='${this.themeColor}' ${this.hideAttribution} hidden
44
49
  ></document-capture-instructions>
45
50
  <document-capture id='document-capture-back' side-of-id='Back' ${this.title} ${this.showNavigation}
46
- ${this.documentCaptureModes} theme-color='${this.themeColor}'
51
+ ${this.documentCaptureModes} theme-color='${this.themeColor}' ${this.hideAttribution}
47
52
  hidden
48
53
  ></document-capture>
49
- <document-capture-review id='front-of-document-capture-review' theme-color='${this.themeColor}' hidden></document-capture-review>
50
- <document-capture-review id='back-of-document-capture-review' theme-color='${this.themeColor}' hidden></document-capture-review>
54
+ <document-capture-review id='front-of-document-capture-review' theme-color='${this.themeColor}' ${this.hideAttribution} hidden></document-capture-review>
55
+ <document-capture-review id='back-of-document-capture-review' theme-color='${this.themeColor}' ${this.hideAttribution} hidden></document-capture-review>
51
56
  </div>
52
57
  `;
53
58
 
@@ -294,6 +299,10 @@ class DocumentCaptureScreens extends HTMLElement {
294
299
  : '';
295
300
  }
296
301
 
302
+ get hideAttribution() {
303
+ return this.hasAttribute('hide-attribution') ? 'hide-attribution' : '';
304
+ }
305
+
297
306
  get themeColor() {
298
307
  return this.getAttribute('theme-color') || '#001096';
299
308
  }
@@ -2,9 +2,11 @@ import './index';
2
2
 
3
3
  const meta = {
4
4
  args: {
5
+ 'hide-attribution': false,
5
6
  'theme-color': '#001096',
6
7
  },
7
8
  argTypes: {
9
+ 'hide-attribution': { control: 'boolean' },
8
10
  'theme-color': { control: 'color' },
9
11
  },
10
12
  component: 'document-capture-screens',
@@ -14,35 +16,35 @@ export default meta;
14
16
 
15
17
  export const DocumentCapture = {
16
18
  render: (args) => `
17
- <document-capture-screens theme-color='${args['theme-color']}'>
19
+ <document-capture-screens theme-color='${args['theme-color']}' ${args['hide-attribution'] ? 'hide-attribution' : ''}>
18
20
  </document-capture-screens>
19
21
  `,
20
22
  };
21
23
 
22
24
  export const DocumentCaptureHiddenInstructions = {
23
25
  render: (args) => `
24
- <document-capture-screens hide-instructions theme-color='${args['theme-color']}'>
26
+ <document-capture-screens hide-instructions theme-color='${args['theme-color']}' ${args['hide-attribution'] ? 'hide-attribution' : ''}>
25
27
  </document-capture-screens>
26
28
  `,
27
29
  };
28
30
 
29
31
  export const DocumentCaptureHideBackOfId = {
30
32
  render: (args) => `
31
- <document-capture-screens hide-back-of-id theme-color='${args['theme-color']}'>
33
+ <document-capture-screens hide-back-of-id theme-color='${args['theme-color']}' ${args['hide-attribution'] ? 'hide-attribution' : ''}>
32
34
  </document-capture-screens>
33
35
  `,
34
36
  };
35
37
 
36
38
  export const DocumentCaptureAllowAttributes = {
37
39
  render: (args) => `
38
- <document-capture-screens document-capture-screens-modes='camera,upload' theme-color='${args['theme-color']}'>
40
+ <document-capture-screens document-capture-screens-modes='camera,upload' theme-color='${args['theme-color']}' ${args['hide-attribution'] ? 'hide-attribution' : ''}>
39
41
  </document-capture-screens>
40
42
  `,
41
43
  };
42
44
 
43
45
  export const DocumentCaptureHideInstructionNBackOfId = {
44
46
  render: (args) => `
45
- <document-capture-screens hide-back-of-id hide-instructions theme-color='${args['theme-color']}'>
47
+ <document-capture-screens hide-back-of-id hide-instructions theme-color='${args['theme-color']}' ${args['hide-attribution'] ? 'hide-attribution' : ''}>
46
48
  </document-capture-screens>
47
49
  `,
48
50
  };
@@ -168,7 +168,7 @@ function templateString() {
168
168
  ${this.cameraError ? '' : '<p class="spinner"></p>'}
169
169
  ${this.cameraError ? `<p style="--flow-space: 4rem" class='color-red | center'>${this.cameraError}</p>` : '<p style="--flow-space: 4rem">Checking permissions</p>'}
170
170
  </div>
171
- <div class='section | flow ${this.isPortraitCaptureView ? 'portrait' : 'landscape'}'>
171
+ <div class='section | flow ${this.isPortraitCaptureView ? 'portrait' : 'landscape'}' ${this.cameraError ? 'hidden' : ''}>
172
172
  <div class='id-video-container'>
173
173
  <div class='id-video ${this.isPortraitCaptureView ? 'portrait' : 'landscape'}' hidden>
174
174
  </div>
@@ -339,71 +339,84 @@ class DocumentCapture extends HTMLElement {
339
339
  }
340
340
 
341
341
  handleIDStream(stream) {
342
- const videoExists = this.shadowRoot.querySelector('canvas');
343
- if (videoExists) {
344
- // remove canvas
345
- videoExists.remove();
346
- }
347
- let video = null;
348
- let canvas = null;
349
- video = document.createElement('video');
350
- canvas = document.createElement('canvas');
351
- const videoContainer = this.shadowRoot.querySelector('.id-video-container');
352
-
353
- video.muted = true;
354
- video.setAttribute('muted', 'true');
355
-
356
- video.autoplay = true;
357
- video.playsInline = true;
358
- if ('srcObject' in video) {
359
- video.srcObject = stream;
360
- } else {
361
- video.src = window.URL.createObjectURL(stream);
362
- }
363
-
364
- canvas.width = videoContainer.clientWidth;
365
- canvas.height = (videoContainer.clientWidth * 9) / 16;
366
- if (this.isPortraitCaptureView) {
367
- canvas.height = (videoContainer.clientWidth * 16) / 9;
368
- }
342
+ try {
343
+ const videoExists = this.shadowRoot.querySelector('canvas');
344
+ if (videoExists) {
345
+ // remove canvas
346
+ videoExists.remove();
347
+ }
348
+ let video = null;
349
+ let canvas = null;
350
+ video = document.createElement('video');
351
+ canvas = document.createElement('canvas');
352
+ const videoContainer = this.shadowRoot.querySelector(
353
+ '.id-video-container',
354
+ );
369
355
 
370
- video.onloadedmetadata = () => {
371
- video.play();
356
+ video.muted = true;
357
+ video.setAttribute('muted', 'true');
372
358
 
373
- this.shadowRoot.querySelector('#loader').hidden = true;
374
- this.shadowRoot.querySelector('.id-video').hidden = false;
375
- this.shadowRoot.querySelector('.actions').hidden = false;
376
- if (!videoExists) {
377
- videoContainer.prepend(canvas);
359
+ video.autoplay = true;
360
+ video.playsInline = true;
361
+ if ('srcObject' in video) {
362
+ video.srcObject = stream;
363
+ } else {
364
+ video.src = window.URL.createObjectURL(stream);
378
365
  }
379
- };
380
366
 
381
- const onVideoStart = () => {
382
- if (video.paused || video.ended) return;
383
- video.removeEventListener('playing', onVideoStart);
384
- const aspectRatio = video.videoWidth / video.videoHeight;
385
- const portrait = aspectRatio < 1;
367
+ canvas.width = videoContainer.clientWidth;
368
+ canvas.height = (videoContainer.clientWidth * 9) / 16;
386
369
  if (this.isPortraitCaptureView) {
387
- this.updatePortraitId(canvas, video);
388
- requestAnimationFrame(onVideoStart);
389
- return;
370
+ canvas.height = (videoContainer.clientWidth * 16) / 9;
390
371
  }
391
372
 
392
- if (portrait) {
393
- videoContainer.classList.add('mobile-camera-screen');
394
- const intermediateCanvas = document.createElement('canvas');
395
- this._capturePortraitToLandscapeImage(intermediateCanvas, video);
396
- this._drawLandscapeImageFromCanvas(canvas, intermediateCanvas);
397
- } else {
398
- this._drawLandscapeImage(canvas, video);
399
- }
400
- requestAnimationFrame(onVideoStart);
401
- };
373
+ video.onloadedmetadata = () => {
374
+ video.play();
375
+
376
+ this.shadowRoot.querySelector('#loader').hidden = true;
377
+ this.shadowRoot.querySelector('.id-video').hidden = false;
378
+ this.shadowRoot.querySelector('.actions').hidden = false;
379
+ if (!videoExists) {
380
+ videoContainer.prepend(canvas);
381
+ }
382
+ };
383
+
384
+ const onVideoStart = () => {
385
+ if (video.paused || video.ended) return;
386
+ video.removeEventListener('playing', onVideoStart);
387
+ const aspectRatio = video.videoWidth / video.videoHeight;
388
+ const portrait = aspectRatio < 1;
389
+ if (this.isPortraitCaptureView) {
390
+ this.updatePortraitId(canvas, video);
391
+ requestAnimationFrame(onVideoStart);
392
+ return;
393
+ }
394
+
395
+ if (portrait) {
396
+ videoContainer.classList.add('mobile-camera-screen');
397
+ const intermediateCanvas = document.createElement('canvas');
398
+ this._capturePortraitToLandscapeImage(intermediateCanvas, video);
399
+ this._drawLandscapeImageFromCanvas(canvas, intermediateCanvas);
400
+ } else {
401
+ this._drawLandscapeImage(canvas, video);
402
+ }
403
+ requestAnimationFrame(onVideoStart);
404
+ };
402
405
 
403
- video.addEventListener('playing', onVideoStart);
406
+ video.addEventListener('playing', onVideoStart);
404
407
 
405
- this._IDStream = stream;
406
- this._IDVideo = video;
408
+ this._IDStream = stream;
409
+ this._IDVideo = video;
410
+ } catch (error) {
411
+ this.setAttribute(
412
+ 'data-camera-error',
413
+ SmartCamera.handleCameraError(error),
414
+ );
415
+ if (error.name !== 'AbortError') {
416
+ console.error(error);
417
+ }
418
+ SmartCamera.stopMedia();
419
+ }
407
420
  }
408
421
 
409
422
  _drawLandscapeImage(
@@ -731,10 +744,12 @@ class DocumentCapture extends HTMLElement {
731
744
 
732
745
  handleBackEvents() {
733
746
  this.dispatchEvent(new CustomEvent('document-capture.cancelled'));
747
+ SmartCamera.stopMedia();
734
748
  }
735
749
 
736
750
  handleCloseEvents() {
737
751
  this.dispatchEvent(new CustomEvent('document-capture.close'));
752
+ SmartCamera.stopMedia();
738
753
  }
739
754
  }
740
755
 
@@ -3,7 +3,9 @@ import './selfie-capture-instructions';
3
3
  import './selfie-capture-review';
4
4
  import SmartCamera from '../../../domain/camera/src/SmartCamera';
5
5
  import styles from '../../../styles/src/styles';
6
- import { version as COMPONENTS_VERSION } from '../../../package.json';
6
+ import packageJson from '../../../package.json';
7
+
8
+ const COMPONENTS_VERSION = packageJson.version;
7
9
 
8
10
  async function getPermissions(captureScreen, facingMode = 'user') {
9
11
  try {
@@ -55,8 +57,9 @@ class SelfieCaptureScreens extends HTMLElement {
55
57
 
56
58
  // If the initial screen is selfie-capture, we need to get permissions
57
59
  if (this.getAttribute('initial-screen') === 'selfie-capture') {
58
- getPermissions(this.selfieCapture, this.getAgentMode());
59
- this.setActiveScreen(this.selfieCapture);
60
+ getPermissions(this.selfieCapture, this.getAgentMode()).then(() =>
61
+ this.setActiveScreen(this.selfieCapture),
62
+ );
60
63
  } else if (this.hideInstructions) {
61
64
  this.setActiveScreen(this.selfieCapture);
62
65
  } else {
@@ -83,8 +86,9 @@ class SelfieCaptureScreens extends HTMLElement {
83
86
  this.selfieInstruction.addEventListener(
84
87
  'selfie-capture-instructions.capture',
85
88
  async () => {
86
- await getPermissions(this.selfieCapture, this.getAgentMode());
87
- this.setActiveScreen(this.selfieCapture);
89
+ await getPermissions(this.selfieCapture, this.getAgentMode()).then(() =>
90
+ this.setActiveScreen(this.selfieCapture),
91
+ );
88
92
  },
89
93
  );
90
94
  this.selfieInstruction.addEventListener(
@@ -1,7 +1,12 @@
1
1
  import './SelfieCaptureScreens';
2
2
 
3
3
  const meta = {
4
+ args: {
5
+ 'hide-attribution': false,
6
+ 'theme-color': '#001096',
7
+ },
4
8
  argTypes: {
9
+ 'hide-attribution': { control: 'boolean' },
5
10
  'theme-color': { control: 'color' },
6
11
  },
7
12
  component: 'selfie-capture-screens',
@@ -10,21 +15,15 @@ const meta = {
10
15
  export default meta;
11
16
 
12
17
  export const SelfieCaptureFlow = {
13
- args: {
14
- 'theme-color': '#001096',
15
- },
16
18
  render: (args) => `
17
- <selfie-capture-screens theme-color='${args['theme-color']}'>
19
+ <selfie-capture-screens theme-color='${args['theme-color']}' ${args['hide-attribution'] ? 'hide-attribution' : ''}>
18
20
  </selfie-capture-screens>
19
21
  `,
20
22
  };
21
23
 
22
24
  export const SelfieCaptureFlowHiddenInstructions = {
23
- args: {
24
- 'theme-color': '#001096',
25
- },
26
25
  render: (args) => `
27
- <selfie-capture-screens hide-instructions theme-color='${args['theme-color']}'>
26
+ <selfie-capture-screens hide-instructions theme-color='${args['theme-color']}' ${args['hide-attribution'] ? 'hide-attribution' : ''}>
28
27
  </selfie-capture-screens>
29
28
  `,
30
29
  };
@@ -514,7 +514,11 @@ function templateString() {
514
514
  <smileid-navigation theme-color='${this.themeColor}' ${this.showNavigation ? 'show-navigation' : ''} ${this.hideBack ? 'hide-back' : ''}></smileid-navigation>
515
515
  <h1 class='text-2xl title-color font-bold'>Take a Selfie</h1>
516
516
 
517
- <div class='section | flow'>
517
+ <div className="error">
518
+ ${this.cameraError ? `<p class="color-red">${this.cameraError}</p>` : ''}
519
+ ${this.hideAttribution ? '' : '<powered-by-smile-id></powered-by-smile-id>'}
520
+ </div>
521
+ <div class='section | flow' ${this.cameraError ? 'hidden' : ''}>
518
522
  <div class='video-container'>
519
523
  <div class='video'>
520
524
  </div>
@@ -763,41 +767,47 @@ class SelfieCaptureScreen extends HTMLElement {
763
767
  }
764
768
 
765
769
  handleStream(stream) {
766
- const videoExists = this.shadowRoot.querySelector('video');
767
- let video = null;
768
- if (videoExists) {
769
- video = this.shadowRoot.querySelector('video');
770
- } else {
771
- video = document.createElement('video');
772
- }
770
+ try {
771
+ const videoExists = this.shadowRoot.querySelector('video');
772
+ let video = null;
773
+ if (videoExists) {
774
+ video = this.shadowRoot.querySelector('video');
775
+ } else {
776
+ video = document.createElement('video');
777
+ }
773
778
 
774
- video.autoplay = true;
775
- video.playsInline = true;
776
- video.muted = true;
779
+ video.autoplay = true;
780
+ video.playsInline = true;
781
+ video.muted = true;
777
782
 
778
- if ('srcObject' in video) {
779
- video.srcObject = stream;
780
- } else {
781
- video.src = window.URL.createObjectURL(stream);
782
- }
783
+ if ('srcObject' in video) {
784
+ video.srcObject = stream;
785
+ } else {
786
+ video.src = window.URL.createObjectURL(stream);
787
+ }
783
788
 
784
- video.onloadedmetadata = () => {
785
- video.play();
786
- };
787
- this._video = video;
788
- const videoContainer = this.shadowRoot.querySelector(
789
- '.video-container > .video',
790
- );
791
- this._data.permissionGranted = true;
789
+ video.onloadedmetadata = () => {
790
+ video.play();
791
+ };
792
792
 
793
- video.onloadedmetadata = () => {
794
- // this.shadowRoot.querySelector('.actions').hidden = false;
795
- // this.shadowRoot.querySelector('#loader').hidden = true;
796
- // this.shadowRoot.querySelector('.video-section').hidden = false;
797
- };
793
+ this._video = video;
794
+ const videoContainer = this.shadowRoot.querySelector(
795
+ '.video-container > .video',
796
+ );
797
+ this._data.permissionGranted = true;
798
798
 
799
- if (!videoExists) {
800
- videoContainer.prepend(video);
799
+ if (!videoExists) {
800
+ videoContainer.prepend(video);
801
+ }
802
+ } catch (error) {
803
+ this.setAttribute(
804
+ 'data-camera-error',
805
+ SmartCamera.handleCameraError(error),
806
+ );
807
+ if (error.name !== 'AbortError') {
808
+ console.error(error);
809
+ }
810
+ SmartCamera.stopMedia();
801
811
  }
802
812
  }
803
813
 
@@ -934,13 +944,19 @@ class SelfieCaptureScreen extends HTMLElement {
934
944
  }
935
945
 
936
946
  handleBackEvents() {
937
- SmartCamera.stopMedia();
947
+ this.stopMedia();
938
948
  this.dispatchEvent(new CustomEvent('selfie-capture.cancelled'));
939
949
  }
940
950
 
941
951
  closeWindow() {
952
+ this.stopMedia();
942
953
  this.dispatchEvent(new CustomEvent('selfie-capture.close'));
943
954
  }
955
+
956
+ stopMedia() {
957
+ this.removeAttribute('data-camera-ready');
958
+ SmartCamera.stopMedia();
959
+ }
944
960
  }
945
961
 
946
962
  if ('customElements' in window && !customElements.get('selfie-capture')) {
@@ -305,7 +305,7 @@ function templateString() {
305
305
  </style>
306
306
  ${styles(this.themeColor)}
307
307
  <div id="selfie-capture-instruction-screen" class="flow center">
308
- <smileid-navigation theme-color=${this.themeColor} ${this.showNavigation ? 'show-navigation' : ''} ${this.hideBack ? 'hide-back' : ''}></smileid-navigation>
308
+ <smileid-navigation theme-color=${this.themeColor} ${this.hideBack ? 'hide-back' : ''} ${this.showNavigation ? '' : 'hidden'}></smileid-navigation>
309
309
  <header>
310
310
  <svg xmlns="http://www.w3.org/2000/svg" width="65" height="91" viewBox="0 0 65 91" fill="none">
311
311
  <g clip-path="url(#clip0_604_692)">
@@ -543,7 +543,7 @@ function templateString() {
543
543
  <button id='allow' data-variant='solid full-width' class='button theme-background'>
544
544
  Allow
545
545
  </button>
546
- <button id='cancel' data-variant='outline full-width' class="button" style='--flow-space: 1.5rem'>
546
+ <button id='cancel' data-variant='outline full-width' class="button" style='--flow-space: 1.5rem' ${this.hideBack ? 'hidden' : ''}>
547
547
  Cancel
548
548
  </button>
549
549
  </section>
@@ -629,6 +629,10 @@ class SelfieCaptureInstructions extends HTMLElement {
629
629
  handleCloseEvents() {
630
630
  this.dispatchEvent(new CustomEvent('selfie-capture-instructions.close'));
631
631
  }
632
+
633
+ static get observedAttributes() {
634
+ return ['show-navigation'];
635
+ }
632
636
  }
633
637
 
634
638
  if (
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@smileid/signature-pad",
3
- "version": "1.4.3",
3
+ "version": "1.4.4",
4
4
  "private": "true",
5
5
  "exports": {
6
6
  ".": "./index.js"
@@ -23,7 +23,7 @@
23
23
  "eslint-config-prettier": "^9.1.0",
24
24
  "eslint-plugin-cypress": "^3.3.0",
25
25
  "eslint-plugin-import": "^2.29.1",
26
- "eslint-plugin-jest": "^28.6.0",
26
+ "eslint-plugin-jest": "^28.8.3",
27
27
  "eslint-plugin-prettier": "^5.2.1",
28
28
  "prettier": "^3.3.3"
29
29
  }
@@ -4,8 +4,9 @@ import SmartCamera from '../../../domain/camera/src/SmartCamera';
4
4
  import '../../document/src';
5
5
  import '../../selfie/src';
6
6
  import '../../camera-permission/CameraPermission';
7
+ import packageJson from '../../../package.json';
7
8
 
8
- import { version as COMPONENTS_VERSION } from '../../../package.json';
9
+ const COMPONENTS_VERSION = packageJson.version;
9
10
 
10
11
  function scwTemplateString() {
11
12
  return `
@@ -2,9 +2,11 @@ import './SmartCameraWeb';
2
2
 
3
3
  const meta = {
4
4
  args: {
5
+ 'hide-attribution': false,
5
6
  'theme-color': '#001096',
6
7
  },
7
8
  argTypes: {
9
+ 'hide-attribution': { control: 'boolean' },
8
10
  'theme-color': { control: 'color' },
9
11
  },
10
12
  component: 'smart-camera-web',
@@ -14,35 +16,35 @@ export default meta;
14
16
 
15
17
  export const SmartCameraWeb = {
16
18
  render: (args) => `
17
- <smart-camera-web theme-color='${args['theme-color']}' capture-id show-navigation>
19
+ <smart-camera-web theme-color='${args['theme-color']}' capture-id show-navigation ${args['hide-attribution'] ? 'hide-attribution' : ''}>
18
20
  </smart-camera-web>
19
21
  `,
20
22
  };
21
23
 
22
24
  export const SmartCameraWebWithOutInstructions = {
23
25
  render: (args) => `
24
- <smart-camera-web theme-color='${args['theme-color']}' capture-id hide-instructions>
26
+ <smart-camera-web theme-color='${args['theme-color']}' capture-id hide-instructions ${args['hide-attribution'] ? 'hide-attribution' : ''}>
25
27
  </smart-camera-web>
26
28
  `,
27
29
  };
28
30
 
29
31
  export const SmartCameraWebWithOutNavigation = {
30
32
  render: (args) => `
31
- <smart-camera-web theme-color='${args['theme-color']}' capture-id>
33
+ <smart-camera-web theme-color='${args['theme-color']}' capture-id ${args['hide-attribution'] ? 'hide-attribution' : ''}>
32
34
  </smart-camera-web>
33
35
  `,
34
36
  };
35
37
 
36
38
  export const SmartCameraWebWithOutBackToHost = {
37
39
  render: (args) => `
38
- <smart-camera-web theme-color='${args['theme-color']}' capture-id show-navigation hide-back-to-host>
40
+ <smart-camera-web theme-color='${args['theme-color']}' capture-id show-navigation hide-back-to-host ${args['hide-attribution'] ? 'hide-attribution' : ''}>
39
41
  </smart-camera-web>
40
42
  `,
41
43
  };
42
44
 
43
45
  export const SmartCameraWebWithOutBackId = {
44
46
  render: (args) => `
45
- <smart-camera-web theme-color='${args['theme-color']}' capture-id show-navigation hide-back-of-id>
47
+ <smart-camera-web theme-color='${args['theme-color']}' capture-id show-navigation hide-back-of-id ${args['hide-attribution'] ? 'hide-attribution' : ''}>
46
48
  </smart-camera-web>
47
49
  `,
48
50
  };
@@ -1,5 +1,6 @@
1
1
  describe('SmartCameraWeb', () => {
2
2
  it('shows attribution by default', () => {
3
+ cy.clock();
3
4
  cy.visit('/smart-camera-web');
4
5
  cy.get('smart-camera-web')
5
6
  .shadow()
@@ -7,9 +8,123 @@ describe('SmartCameraWeb', () => {
7
8
  .shadow()
8
9
  .find('powered-by-smile-id')
9
10
  .should('be.visible');
11
+
12
+ cy.get('smart-camera-web')
13
+ .shadow()
14
+ .find('selfie-capture-instructions')
15
+ .shadow()
16
+ .find('#allow')
17
+ .click();
18
+
19
+ cy.get('smart-camera-web')
20
+ .shadow()
21
+ .find('selfie-capture')
22
+ .shadow()
23
+ .find('powered-by-smile-id')
24
+ .should('be.visible');
25
+
26
+ cy.get('smart-camera-web')
27
+ .shadow()
28
+ .find('selfie-capture')
29
+ .shadow()
30
+ .find('#start-image-capture')
31
+ .click();
32
+ cy.tick(8000);
33
+
34
+ cy.get('smart-camera-web')
35
+ .shadow()
36
+ .find('selfie-capture-review')
37
+ .shadow()
38
+ .find('powered-by-smile-id')
39
+ .should('be.visible');
40
+
41
+ cy.get('smart-camera-web')
42
+ .shadow()
43
+ .find('selfie-capture-review')
44
+ .shadow()
45
+ .find('#select-id-image')
46
+ .click();
47
+
48
+ cy.get('smart-camera-web')
49
+ .shadow()
50
+ .find('document-capture-instructions#document-capture-instructions-front')
51
+ .shadow()
52
+ .find('powered-by-smile-id')
53
+ .should('be.visible');
54
+
55
+ cy.get('smart-camera-web')
56
+ .shadow()
57
+ .find('document-capture-instructions#document-capture-instructions-front')
58
+ .shadow()
59
+ .find('#take-photo')
60
+ .click();
61
+
62
+ cy.get('smart-camera-web')
63
+ .shadow()
64
+ .find('document-capture#document-capture-front')
65
+ .shadow()
66
+ .find('powered-by-smile-id')
67
+ .should('be.visible');
68
+
69
+ cy.get('smart-camera-web')
70
+ .shadow()
71
+ .find('document-capture#document-capture-front')
72
+ .shadow()
73
+ .find('#capture-id-image')
74
+ .click();
75
+
76
+ cy.get('smart-camera-web')
77
+ .shadow()
78
+ .find('document-capture-review#front-of-document-capture-review')
79
+ .shadow()
80
+ .find('powered-by-smile-id')
81
+ .should('be.visible');
82
+
83
+ cy.get('smart-camera-web')
84
+ .shadow()
85
+ .find('document-capture-review#front-of-document-capture-review')
86
+ .shadow()
87
+ .find('#select-id-image')
88
+ .click();
89
+
90
+ cy.get('smart-camera-web')
91
+ .shadow()
92
+ .find('document-capture-instructions#document-capture-instructions-back')
93
+ .shadow()
94
+ .find('powered-by-smile-id')
95
+ .should('be.visible');
96
+
97
+ cy.get('smart-camera-web')
98
+ .shadow()
99
+ .find('document-capture-instructions#document-capture-instructions-back')
100
+ .shadow()
101
+ .find('#take-photo')
102
+ .click();
103
+
104
+ cy.get('smart-camera-web')
105
+ .shadow()
106
+ .find('document-capture#document-capture-back')
107
+ .shadow()
108
+ .find('powered-by-smile-id')
109
+ .should('be.visible');
110
+
111
+ cy.get('smart-camera-web')
112
+ .shadow()
113
+ .find('document-capture#document-capture-back')
114
+ .shadow()
115
+ .find('#capture-id-image')
116
+ .click();
117
+
118
+ cy.get('smart-camera-web')
119
+ .shadow()
120
+ .find('document-capture-review#back-of-document-capture-review')
121
+ .shadow()
122
+ .find('powered-by-smile-id')
123
+ .should('be.visible');
10
124
  });
11
125
 
12
126
  it.only('hides attribution when `hide-attribution` attribute is passed', () => {
127
+ cy.clock();
13
128
  cy.visit('/capture-back-of-id-hide-attribution');
14
129
  cy.get('smart-camera-web')
15
130
  .shadow()
@@ -17,5 +132,118 @@ describe('SmartCameraWeb', () => {
17
132
  .shadow()
18
133
  .get('powered-by-smile-id')
19
134
  .should('not.exist');
135
+
136
+ cy.get('smart-camera-web')
137
+ .shadow()
138
+ .find('selfie-capture-instructions')
139
+ .shadow()
140
+ .find('#allow')
141
+ .click();
142
+
143
+ cy.get('smart-camera-web')
144
+ .shadow()
145
+ .find('selfie-capture')
146
+ .shadow()
147
+ .get('powered-by-smile-id')
148
+ .should('not.exist');
149
+
150
+ cy.get('smart-camera-web')
151
+ .shadow()
152
+ .find('selfie-capture')
153
+ .shadow()
154
+ .find('#start-image-capture')
155
+ .click();
156
+ cy.tick(8000);
157
+
158
+ cy.get('smart-camera-web')
159
+ .shadow()
160
+ .find('selfie-capture-review')
161
+ .shadow()
162
+ .get('powered-by-smile-id')
163
+ .should('not.exist');
164
+
165
+ cy.get('smart-camera-web')
166
+ .shadow()
167
+ .find('selfie-capture-review')
168
+ .shadow()
169
+ .find('#select-id-image')
170
+ .click();
171
+
172
+ cy.get('smart-camera-web')
173
+ .shadow()
174
+ .find('document-capture-instructions#document-capture-instructions-front')
175
+ .shadow()
176
+ .get('powered-by-smile-id')
177
+ .should('not.exist');
178
+
179
+ cy.get('smart-camera-web')
180
+ .shadow()
181
+ .find('document-capture-instructions#document-capture-instructions-front')
182
+ .shadow()
183
+ .find('#take-photo')
184
+ .click();
185
+
186
+ cy.get('smart-camera-web')
187
+ .shadow()
188
+ .find('document-capture#document-capture-front')
189
+ .shadow()
190
+ .get('powered-by-smile-id')
191
+ .should('not.exist');
192
+
193
+ cy.get('smart-camera-web')
194
+ .shadow()
195
+ .find('document-capture#document-capture-front')
196
+ .shadow()
197
+ .find('#capture-id-image')
198
+ .click();
199
+
200
+ cy.get('smart-camera-web')
201
+ .shadow()
202
+ .find('document-capture-review#front-of-document-capture-review')
203
+ .shadow()
204
+ .get('powered-by-smile-id')
205
+ .should('not.exist');
206
+
207
+ cy.get('smart-camera-web')
208
+ .shadow()
209
+ .find('document-capture-review#front-of-document-capture-review')
210
+ .shadow()
211
+ .find('#select-id-image')
212
+ .click();
213
+
214
+ cy.get('smart-camera-web')
215
+ .shadow()
216
+ .find('document-capture-instructions#document-capture-instructions-back')
217
+ .shadow()
218
+ .get('powered-by-smile-id')
219
+ .should('not.exist');
220
+
221
+ cy.get('smart-camera-web')
222
+ .shadow()
223
+ .find('document-capture-instructions#document-capture-instructions-back')
224
+ .shadow()
225
+ .find('#take-photo')
226
+ .click();
227
+
228
+ cy.get('smart-camera-web')
229
+ .shadow()
230
+ .find('document-capture#document-capture-back')
231
+ .shadow()
232
+ .get('powered-by-smile-id')
233
+ .should('not.exist');
234
+
235
+ cy.get('smart-camera-web')
236
+ .shadow()
237
+ .find('document-capture#document-capture-back')
238
+ .shadow()
239
+ .find('#capture-id-image')
240
+ .click();
241
+
242
+ cy.get('smart-camera-web')
243
+ .shadow()
244
+ .find('document-capture-review#back-of-document-capture-review')
245
+ .shadow()
246
+ .get('powered-by-smile-id')
247
+ .should('not.exist');
20
248
  });
21
249
  });
@@ -296,7 +296,7 @@ context('SmartCameraWeb', () => {
296
296
  .should('not.be.visible');
297
297
  });
298
298
 
299
- it('should switch to request screen when "Rest"', () => {
299
+ it('should switch to request screen when "Reset"', () => {
300
300
  cy.get('smart-camera-web').then((element) => {
301
301
  element[0].reset();
302
302
  });
@@ -0,0 +1,34 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+
4
+ const componentsDir = './components';
5
+ const outputFilePath = './index.js';
6
+
7
+ const getDirectories = (source) =>
8
+ fs
9
+ .readdirSync(source, { withFileTypes: true })
10
+ .filter((dirent) => dirent.isDirectory())
11
+ .map((dirent) => dirent.name);
12
+
13
+ const generateExports = () => {
14
+ const componentDirs = getDirectories(componentsDir);
15
+ let exportStatements = '';
16
+
17
+ componentDirs.forEach((dir) => {
18
+ const srcPath = path.join(componentsDir, dir, 'src');
19
+ if (fs.existsSync(srcPath)) {
20
+ const files = fs.readdirSync(srcPath);
21
+ files.forEach((file) => {
22
+ const fileName = path.parse(file).name;
23
+ const exportName = fileName.charAt(0).toUpperCase() + fileName.slice(1);
24
+ exportStatements += `import ${exportName} from './components/${dir}/src/${fileName}';\n`;
25
+ exportStatements += `export { ${exportName} };\n`;
26
+ });
27
+ }
28
+ });
29
+
30
+ fs.writeFileSync(outputFilePath, exportStatements);
31
+ };
32
+
33
+ generateExports();
34
+ export default generateExports;
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "@smileid/web-components",
3
- "version": "1.4.3",
3
+ "version": "1.4.5-alpha.0",
4
+ "main": "index.js",
4
5
  "exports": {
5
6
  ".": "./index.js",
6
7
  "./combobox": "./components/combobox/src/index.js",
@@ -32,14 +33,14 @@
32
33
  "validate.js": "^0.13.1"
33
34
  },
34
35
  "devDependencies": {
35
- "cypress": "^13.14.1",
36
- "esbuild": "^0.21.5",
36
+ "cypress": "^13.15.0",
37
+ "esbuild": "^0.24.0",
37
38
  "eslint": "^8.57.0",
38
39
  "eslint-config-airbnb-base": "^15.0.0",
39
40
  "eslint-config-prettier": "^9.1.0",
40
41
  "eslint-plugin-cypress": "^3.3.0",
41
42
  "eslint-plugin-import": "^2.29.1",
42
- "eslint-plugin-jest": "^28.6.0",
43
+ "eslint-plugin-jest": "^28.8.3",
43
44
  "eslint-plugin-prettier": "^5.2.1",
44
45
  "prettier": "^3.3.3"
45
46
  }