diff --git a/packages/components/document-capture/id-review/src/IdReview.js b/packages/components/document-capture/id-review/src/IdReview.js
new file mode 100644
index 00000000..62fe3b21
--- /dev/null
+++ b/packages/components/document-capture/id-review/src/IdReview.js
@@ -0,0 +1,339 @@
+import styles from '../../../styles';
+
+function templateString() {
+ return `
+ ${styles}
+
+
+ ${this.showNavigation ? `
+
+
+
+ ` : ''}
+
+
Make sure all corners of the document
+ are visible and there is no glare
+
+
+ ${this.imageSrc ? `
` : ''}
+
+
+
+
+
+
+ ${this.hideAttribution ? '' : `
+
+ `}
+
+
+ `;
+}
+
+class IdReview extends HTMLElement {
+ constructor() {
+ super();
+ this.templateString = templateString.bind(this);
+ this.render = () => this.templateString();
+
+ this.attachShadow({ mode: 'open' });
+ }
+
+ connectedCallback() {
+ const template = document.createElement('template');
+ template.innerHTML = this.render();
+ this.shadowRoot.innerHTML = '';
+ this.shadowRoot.appendChild(template.content.cloneNode(true));
+ this.setUpEventListeners();
+ }
+
+ static get observedAttributes() {
+ return ['hide-back-to-host', 'show-navigation', 'data-image'];
+ }
+
+ get hideBack() {
+ return this.hasAttribute('hide-back-to-host');
+ }
+
+ get showNavigation() {
+ return this.hasAttribute('show-navigation');
+ }
+
+ get themeColor() {
+ return this.getAttribute('theme-color') || '#043C93';
+ }
+
+ get hideAttribution() {
+ return this.hasAttribute('hide-attribution');
+ }
+
+ get imageSrc() {
+ return this.getAttribute('data-image');
+ }
+
+ get title() {
+ return this.getAttribute('title') || 'Submit Front of ID';
+ }
+
+ handleBackEvents() {
+ this.dispatchEvent(new CustomEvent('SmileIdentity::Exit'));
+ }
+
+ closeWindow() {
+ const referenceWindow = window.parent;
+ referenceWindow.postMessage('SmileIdentity::Close', '*');
+ }
+
+ attributeChangedCallback(name) {
+ switch (name) {
+ case 'data-image':
+ case 'hide-back-to-host':
+ case 'show-navigation':
+ this.shadowRoot.innerHTML = this.render();
+ this.setUpEventListeners();
+ break;
+ default:
+ break;
+ }
+ }
+
+ setUpEventListeners() {
+ this.selectIDImage = this.shadowRoot.querySelector('#select-id-image');
+ this.reCaptureIDImage = this.shadowRoot.querySelector('#re-capture-id-image');
+ const CloseIframeButtons = this.shadowRoot.querySelectorAll('.close-iframe');
+
+ if (this.backButton) {
+ this.backButton.addEventListener('click', (e) => {
+ this.handleBackEvents(e);
+ });
+ }
+ CloseIframeButtons.forEach((button) => {
+ button.addEventListener(
+ 'click',
+ () => {
+ this.closeWindow();
+ },
+ false,
+ );
+ });
+
+ this.selectIDImage.addEventListener('click', () => {
+ this.dispatchEvent(
+ new CustomEvent('IdReview::SelectImage', {
+ detail: {},
+ }),
+ );
+ });
+ this.reCaptureIDImage.addEventListener('click', () => {
+ this.dispatchEvent(
+ new CustomEvent('IdReview::ReCaptureID', {
+ detail: {},
+ }),
+ );
+ });
+ }
+}
+
+if ('customElements' in window && !customElements.get('id-review')) {
+ window.customElements.define('id-review', IdReview);
+}
+
+export default IdReview;
diff --git a/packages/components/document-capture/id-review/src/IdReview.stories.js b/packages/components/document-capture/id-review/src/IdReview.stories.js
new file mode 100644
index 00000000..86461405
--- /dev/null
+++ b/packages/components/document-capture/id-review/src/IdReview.stories.js
@@ -0,0 +1,14 @@
+import './index';
+
+const meta = {
+ component: 'id-review',
+};
+
+export default meta;
+
+export const IdReview = {
+ render: () => `
+
+
+ `,
+};
diff --git a/packages/components/document-capture/id-review/src/index.js b/packages/components/document-capture/id-review/src/index.js
new file mode 100644
index 00000000..6dfdc065
--- /dev/null
+++ b/packages/components/document-capture/id-review/src/index.js
@@ -0,0 +1,3 @@
+import IdReview from './IdReview';
+
+export default IdReview;