+
- {isSpinnerVisible ? renderPendingMessage() : renderActionButtons()}
-
- {isSpinnerVisible && (
-
+ {isSmallScreen ? (
+
+ ) : (
+
)}
);
-
- function renderActionButtons() {
- return (
- <>
- {isMobile() && (
-
- {`Launch ${name}`}
-
- )}
-
- {isQRCodeVisible && renderQRCode()}
-
- {!isQRCodeVisible && (
-
- )}
- >
- );
- }
-
- function renderQRCode() {
- return (
-
-
- {`Scan QR code with ${name}`}
-
-
-
- );
- }
-
- function renderPendingMessage() {
- return (
-
-
-
-
-
-
- {`Please wait while we connect you to ${name}...`}
-
-
- );
- }
-
- function handleToggleSpinnerVisibility() {
- setSpinnerVisibility(!isSpinnerVisible);
- }
-
- function handleToggleQRCodeVisibility() {
- setQRCodeVisibility(!isQRCodeVisible);
- }
-
- function handleCancelClick() {
- onClose();
- }
}
export default PeraWalletConnectModal;
diff --git a/src/modal/_pera-wallet-connect-modal.scss b/src/modal/_pera-wallet-connect-modal.scss
deleted file mode 100644
index 3af0f0b..0000000
--- a/src/modal/_pera-wallet-connect-modal.scss
+++ /dev/null
@@ -1,73 +0,0 @@
-.pera-wallet-connect-modal__display-qr-code-button,
-.pera-wallet-connect-modal__launch-pera-wallet-button {
- letter-spacing: -0.3px;
-}
-
-.pera-wallet-connect-modal__launch-pera-wallet-button {
- display: block;
-
- padding: 14px;
- margin-bottom: 20px;
-
- border-radius: 4px;
- background-color: var(--pera-wallet-main-color);
-
- color: black;
-
- text-decoration: none;
- text-align: center;
- font-size: 14px;
-}
-
-.pera-wallet-connect-modal__cancel-button,
-.pera-wallet-connect-modal__display-qr-code-button {
- width: 100%;
-
- padding: 14px;
- margin: 0;
-
- background-color: white;
- border: 1px solid black;
- border-radius: 4px;
-
- color: black;
-}
-
-.pera-wallet-connect-modal__qr-code {
- cursor: none;
-
- text-align: center;
-}
-
-.pera-wallet-connect-modal__qr-code__text {
- margin-bottom: 15px;
-}
-
-.pera-wallet-connect-modal__pending-message {
- display: flex;
- align-items: center;
- justify-content: center;
- flex-direction: column;
-
- height: 150px;
-
- text-align: center;
-}
-
-.pera-wallet-connect-modal__pending-message__logo img {
- width: 40px;
-}
-
-.pera-wallet-connect-modal__pending-message__text {
- margin-top: 25px;
-}
-
-.pera-wallet-connect-modal__cancel-button {
- margin-top: 20px;
-
- border-color: rgba(0, 0, 0, 0.08);
-
- color: rgba(0, 0, 0, 0.8);
-
- font-size: 12px;
-}
diff --git a/src/modal/_pera-wallet-modal.scss b/src/modal/_pera-wallet-modal.scss
index 3e075ff..716f722 100644
--- a/src/modal/_pera-wallet-modal.scss
+++ b/src/modal/_pera-wallet-modal.scss
@@ -1,18 +1,15 @@
-.pera-wallet-connect-modal {
- --pera-wallet-connect-modal-font-family: ui-rounded, "SF Pro Rounded", "SF Pro Text",
- medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, ui-sans-serif,
- "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue",
- sans-serif;
+@import url("https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap");
+@import "../ui/styles/media-queries";
- display: flex;
- align-items: center;
- justify-content: center;
+.pera-wallet-connect-modal {
+ --pera-wallet-connect-modal-font-family: "Inter", sans-serif;
position: fixed;
top: 0;
right: 0;
left: 0;
bottom: 0;
+ z-index: 10;
width: 100vw;
height: 100vh;
@@ -24,6 +21,13 @@
* {
box-sizing: border-box;
}
+
+ li {
+ list-style-type: none;
+
+ margin: 0;
+ padding: 0;
+ }
}
.pera-wallet-connect-button {
@@ -32,12 +36,12 @@
justify-content: center;
width: auto;
- height: 35px;
+ height: 48px;
padding: 14px;
border: none;
- border-radius: var(--small-radius-size);
+ border-radius: 12px;
outline: none;
cursor: pointer;
@@ -53,39 +57,116 @@
}
.pera-wallet-connect-modal__close-button {
- width: 30px;
- height: 30px;
+ width: 40px;
+ height: 40px;
margin: 0;
padding: 0;
- box-shadow: 1px 2px 2px rgba(0, 0, 0, 0.08);
- background-color: white;
+ background: #333333;
+ border: 1.5px solid rgba(255, 255, 255, 0.08);
+ box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.15);
border-radius: 100%;
}
.pera-wallet-connect-modal__body {
position: relative;
+ top: 50%;
+ left: 50%;
- width: 440px;
+ width: 655px;
max-width: calc(100vw - 80px);
- padding: 24px;
+ padding: 28px;
+
+ background-color: #edeffb;
- background-color: white;
box-shadow: 1px 2px 2px rgba(0, 0, 0, 0.08);
- border-radius: 4px;
+ border-radius: 24px;
+
+ transform: translate(-50%, -50%);
+
+ &::before {
+ --background-line: #1e0972 0 1.2px, transparent 0 calc(100% - 1.2px), #1e0972;
+
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: -1;
+
+ content: "";
+
+ background-image: linear-gradient(var(--background-line)),
+ linear-gradient(90deg, var(--background-line));
+ background-size: 116px 116px;
+
+ mix-blend-mode: overlay;
+
+ border-radius: 24px;
+
+ opacity: 0.8;
+
+ pointer-events: none;
+ }
}
.pera-wallet-connect-modal__body__header {
display: flex;
align-items: center;
- justify-content: space-between;
+ justify-content: flex-end;
position: absolute;
- top: -40px;
- right: 0;
+ top: -44px;
+ right: -44px;
left: 0;
}
+
+@include for-small-screens {
+ .pera-wallet-connect-modal__body {
+ top: 40px;
+ bottom: 0;
+ left: 0;
+
+ width: 100%;
+ max-width: unset;
+ height: calc(calc(100 * var(--vh)));
+
+ padding: 20px;
+
+ background-color: #ffffff;
+
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.02), 0 4px 12px rgba(0, 0, 0, 0.03);
+
+ border-radius: 20px 20px 0px 0px;
+
+ transform: unset;
+
+ &::before {
+ background-image: unset;
+ }
+ }
+
+ .pera-wallet-connect-modal__body__header {
+ display: flex;
+ align-items: center;
+ justify-content: flex-end;
+
+ position: static;
+ }
+
+ .pera-wallet-connect-modal__close-button {
+ width: 24px;
+ height: 24px;
+
+ margin: 0;
+ padding: 0;
+
+ background: transparent;
+ border: unset;
+ box-shadow: unset;
+ }
+}
diff --git a/src/modal/component/accordion/Accordion.tsx b/src/modal/component/accordion/Accordion.tsx
new file mode 100644
index 0000000..8edd270
--- /dev/null
+++ b/src/modal/component/accordion/Accordion.tsx
@@ -0,0 +1,36 @@
+import React, {useState} from "react";
+
+import AccordionItem from "./item/AccordionItem";
+import {AccordionData} from "./util/accordionTypes";
+
+interface AccordionProps {
+ items: AccordionData[];
+}
+
+function Accordion({items}: AccordionProps) {
+ const [activeItem, setActiveItem] = useState(0);
+
+ return (
+
+ {items.map((item, index) => (
+
+ ))}
+
+ );
+
+ function handleToggle(index: number) {
+ return () => {
+ if (activeItem === index) {
+ setActiveItem(0);
+ }
+ setActiveItem(index);
+ };
+ }
+}
+
+export default Accordion;
diff --git a/src/modal/component/accordion/button/AccordionButton.tsx b/src/modal/component/accordion/button/AccordionButton.tsx
new file mode 100644
index 0000000..584f717
--- /dev/null
+++ b/src/modal/component/accordion/button/AccordionButton.tsx
@@ -0,0 +1,22 @@
+import "./_accordion-button.scss";
+
+import React from "react";
+
+import AccordionIcon from "../icon/AccordionIcon";
+
+interface AccordionButtonProps {
+ children: React.ReactNode;
+ onClick: VoidFunction;
+}
+
+function AccordionButton({children, onClick}: AccordionButtonProps) {
+ return (
+
+ );
+}
+
+export default AccordionButton;
diff --git a/src/modal/component/accordion/button/_accordion-button.scss b/src/modal/component/accordion/button/_accordion-button.scss
new file mode 100644
index 0000000..562affa
--- /dev/null
+++ b/src/modal/component/accordion/button/_accordion-button.scss
@@ -0,0 +1,26 @@
+.pera-wallet-accordion-button {
+ display: flex;
+ align-items: center;
+
+ gap: 16px;
+
+ width: 100%;
+
+ padding: 12px 24px;
+
+ color: #2c3559;
+ background-color: #ffffff;
+
+ border: none;
+ border-radius: 24px;
+ outline: none;
+
+ cursor: pointer;
+
+ font-size: 16px;
+ line-height: 18px;
+ letter-spacing: -0.1px;
+ font-weight: 600;
+
+ transition: all ease-in 0.2s;
+}
diff --git a/src/modal/component/accordion/icon/AccordionIcon.tsx b/src/modal/component/accordion/icon/AccordionIcon.tsx
new file mode 100644
index 0000000..ac24598
--- /dev/null
+++ b/src/modal/component/accordion/icon/AccordionIcon.tsx
@@ -0,0 +1,9 @@
+import RightIcon from "../../../../asset/icon/Right.svg";
+
+import React from "react";
+
+function AccordionIcon() {
+ return
;
+}
+
+export default AccordionIcon;
diff --git a/src/modal/component/accordion/item/AccordionItem.tsx b/src/modal/component/accordion/item/AccordionItem.tsx
new file mode 100644
index 0000000..95018be
--- /dev/null
+++ b/src/modal/component/accordion/item/AccordionItem.tsx
@@ -0,0 +1,30 @@
+import "./_accordion-item.scss";
+
+import React from "react";
+
+import AccordionButton from "../button/AccordionButton";
+import AccordionPanel from "../panel/AccordionPanel";
+import {AccordionData} from "../util/accordionTypes";
+
+interface AccordionItemProps {
+ data: AccordionData;
+ onToggle: VoidFunction;
+ isActive: boolean;
+}
+
+function AccordionItem({data, onToggle, isActive}: AccordionItemProps) {
+ const {title, description} = data;
+
+ return (
+
+ {title}
+
+ {description}
+
+ );
+}
+
+export default AccordionItem;
diff --git a/src/modal/component/accordion/item/_accordion-item.scss b/src/modal/component/accordion/item/_accordion-item.scss
new file mode 100644
index 0000000..9de3b8c
--- /dev/null
+++ b/src/modal/component/accordion/item/_accordion-item.scss
@@ -0,0 +1,31 @@
+.pera-wallet-accordion-item {
+ background-color: #ffffff;
+
+ border-radius: 24px;
+
+ &:not(:last-of-type) {
+ margin-bottom: 20px;
+ }
+}
+
+.pera-wallet-accordion-item--active {
+ .pera-wallet-accordion-panel {
+ height: 296px;
+
+ border-radius: 0 0 24px 24px;
+
+ transition: height ease-in 0.2s;
+ }
+
+ .pera-wallet-accordion-button {
+ padding: 28px 24px 12px;
+
+ border-radius: 24px 24px 0 0;
+
+ transition: all ease-in 0.2s;
+ }
+
+ .pera-wallet-accordion-icon {
+ transform: rotate(90deg);
+ }
+}
diff --git a/src/modal/component/accordion/panel/AccordionPanel.tsx b/src/modal/component/accordion/panel/AccordionPanel.tsx
new file mode 100644
index 0000000..a1016e8
--- /dev/null
+++ b/src/modal/component/accordion/panel/AccordionPanel.tsx
@@ -0,0 +1,17 @@
+import "./_accordion-panel.scss";
+
+import React from "react";
+
+interface AccordionPanelProps {
+ children: React.ReactNode;
+}
+
+function AccordionPanel({children}: AccordionPanelProps) {
+ return (
+
+ );
+}
+
+export default AccordionPanel;
diff --git a/src/modal/component/accordion/panel/_accordion-panel.scss b/src/modal/component/accordion/panel/_accordion-panel.scss
new file mode 100644
index 0000000..8e0d23d
--- /dev/null
+++ b/src/modal/component/accordion/panel/_accordion-panel.scss
@@ -0,0 +1,14 @@
+.pera-wallet-accordion-panel {
+ height: 0;
+ overflow: hidden;
+
+ color: #69708d;
+ background-color: #ffffff;
+
+ font-size: 13px;
+ font-weight: 500;
+ line-height: 20px;
+ letter-spacing: -0.04px;
+
+ transition: height ease-in 0.2s;
+}
diff --git a/src/modal/component/accordion/util/accordionTypes.ts b/src/modal/component/accordion/util/accordionTypes.ts
new file mode 100644
index 0000000..e48284c
--- /dev/null
+++ b/src/modal/component/accordion/util/accordionTypes.ts
@@ -0,0 +1,7 @@
+import React from "react";
+
+export interface AccordionData {
+ id: string;
+ title: string;
+ description: React.ReactNode;
+}
diff --git a/src/modal/mode/desktop/PeraWalletConnectModalDesktopMode.tsx b/src/modal/mode/desktop/PeraWalletConnectModalDesktopMode.tsx
new file mode 100644
index 0000000..b9c29f4
--- /dev/null
+++ b/src/modal/mode/desktop/PeraWalletConnectModalDesktopMode.tsx
@@ -0,0 +1,25 @@
+import "./_pera-wallet-connect-modal-desktop-mode.scss";
+
+import React from "react";
+
+import Accordion from "../../component/accordion/Accordion";
+import {getPeraConnectModalAccordionData} from "../../peraWalletConnectModalUtils";
+import PeraWalletConnectModalInformationSection from "../../section/information/PeraWalletConnectModalInformationSection";
+
+interface PeraWalletConnectModalDesktopModeProps {
+ uri: string;
+}
+
+function PeraWalletConnectModalDesktopMode({
+ uri
+}: PeraWalletConnectModalDesktopModeProps) {
+ return (
+
+ );
+}
+
+export default PeraWalletConnectModalDesktopMode;
diff --git a/src/modal/mode/desktop/_pera-wallet-connect-modal-desktop-mode.scss b/src/modal/mode/desktop/_pera-wallet-connect-modal-desktop-mode.scss
new file mode 100644
index 0000000..c3c977a
--- /dev/null
+++ b/src/modal/mode/desktop/_pera-wallet-connect-modal-desktop-mode.scss
@@ -0,0 +1,29 @@
+.pera-wallet-connect-modal-desktop-mode {
+ display: grid;
+ grid-template-columns: 205px auto;
+ gap: 80px;
+}
+
+.pera-wallet-connect-modal-desktop-mode__accordion__description {
+ padding: 0 40px 40px 64px;
+}
+
+.pera-wallet-connect-modal-desktop-mode__pera-download-qr-code {
+ display: flex;
+
+ width: 264px;
+ height: 264px;
+
+ margin: -12px auto 0;
+}
+
+#pera-wallet-connect-modal-desktop-mode__qr-code {
+ width: 164px;
+ height: 164px;
+
+ margin: 0 auto;
+ display: flex;
+ box-shadow: 0px 20px 60px rgba(26, 35, 91, 0.15), 0px 4px 12px rgba(26, 35, 91, 0.05),
+ 0px 1px 4px rgba(26, 35, 91, 0.06);
+ border-radius: 24px;
+}
diff --git a/src/modal/mode/touch-screen/PeraWalletConnectModalTouchScreenMode.tsx b/src/modal/mode/touch-screen/PeraWalletConnectModalTouchScreenMode.tsx
new file mode 100644
index 0000000..a8b3903
--- /dev/null
+++ b/src/modal/mode/touch-screen/PeraWalletConnectModalTouchScreenMode.tsx
@@ -0,0 +1,80 @@
+import "./_pera-wallet-connect-modal-touch-screen-mode.scss";
+
+import React, {useState} from "react";
+
+import {
+ generatePeraWalletConnectDeepLink,
+ getPeraWalletAppMeta
+} from "../../../util/peraWalletUtils";
+import PeraWalletConnectModalInformationSection from "../../section/information/PeraWalletConnectModalInformationSection";
+import PeraWalletConnectModalPendingMessage from "../../section/pending-message/PeraWalletConnectModalPendingMessage";
+
+interface PeraWalletConnectModalTouchScreenModeProps {
+ uri: string;
+}
+function PeraWalletConnectModalTouchScreenMode({
+ uri
+}: PeraWalletConnectModalTouchScreenModeProps) {
+ const [view, setView] = useState("default" as "default" | "launching-app");
+ const {name} = getPeraWalletAppMeta();
+
+ return (
+
+ {view === "launching-app" ? (
+
+ ) : (
+ <>
+
+
+
+ >
+ )}
+
+ );
+
+ function handleChangeModalView() {
+ if (view === "default") {
+ setView("launching-app");
+ } else if (view === "launching-app") {
+ setView("default");
+ }
+ }
+}
+
+export default PeraWalletConnectModalTouchScreenMode;
diff --git a/src/modal/mode/touch-screen/_pera-wallet-connect-modal-touch-screen-mode.scss b/src/modal/mode/touch-screen/_pera-wallet-connect-modal-touch-screen-mode.scss
new file mode 100644
index 0000000..5d4b7e3
--- /dev/null
+++ b/src/modal/mode/touch-screen/_pera-wallet-connect-modal-touch-screen-mode.scss
@@ -0,0 +1,74 @@
+.pera-wallet-connect-modal-touch-screen-mode {
+ display: grid;
+ grid-template-columns: 1fr;
+ gap: 46px;
+
+ padding: 4px;
+
+ &--pending-message-view {
+ gap: 56px;
+ grid-template-rows: auto 48px;
+
+ height: 100%;
+
+ padding-bottom: 70px;
+ }
+}
+
+.pera-wallet-connect-modal-touch-screen-mode__launch-pera-wallet-button,
+.pera-wallet-connect-modal-touch-screen-mode__install-pera-wallet-button {
+ display: block;
+
+ padding: 14px;
+
+ border-radius: 12px;
+
+ text-decoration: none;
+ text-align: center;
+ font-size: 14px;
+ line-height: 20px;
+ letter-spacing: -0.09px;
+ font-weight: 500;
+}
+
+.pera-wallet-connect-modal-touch-screen-mode__launch-pera-wallet-button {
+ margin-bottom: 32px;
+
+ background-color: #6b46fe;
+
+ color: #ffffff;
+}
+
+.pera-wallet-connect-modal-touch-screen-mode__install-pera-wallet-button {
+ margin-bottom: 20px;
+
+ background-color: #f2f3f8;
+
+ color: #2c3559;
+}
+
+.pera-wallet-connect-modal-touch-screen-mode__new-to-pera-box {
+ position: relative;
+
+ margin-bottom: 32px;
+
+ border-top: 1px solid #e6e8ee;
+}
+
+.pera-wallet-connect-modal-touch-screen-mode__new-to-pera-box__text {
+ position: absolute;
+ top: -12px;
+ right: calc(50% - 56px);
+
+ width: 116px;
+
+ color: #69708d;
+ background-color: #ffffff;
+
+ font-size: 13px;
+ font-weight: 500;
+ line-height: 24px;
+ letter-spacing: -0.04px;
+
+ text-align: center;
+}
diff --git a/src/modal/peraWalletConnectModalUtils.tsx b/src/modal/peraWalletConnectModalUtils.tsx
index d335b38..77fc587 100644
--- a/src/modal/peraWalletConnectModalUtils.tsx
+++ b/src/modal/peraWalletConnectModalUtils.tsx
@@ -1,8 +1,13 @@
+import PeraWalletLogoCircleYellow from "../asset/icon/PeraWallet--circle-yellow.svg";
+import PeraWalletLogoCircleBlack from "../asset/icon/PeraWallet--circle-black.svg";
+
import React from "react";
import ReactDOM from "react-dom";
+import {QRCode} from "react-qrcode-logo";
import PeraWalletConnectModal from "./PeraWalletConnectModal";
import PeraWalletRedirectModal from "./redirect/PeraWalletRedirectModal";
+import {AccordionData} from "./component/accordion/util/accordionTypes";
// The ID of the wrapper element for PeraWalletConnectModal
const PERA_WALLET_CONNECT_MODAL_ID = "pera-wallet-connect-modal-wrapper";
@@ -74,6 +79,59 @@ function removeModalWrapperFromDOM(modalId: string) {
}
}
+function getPeraConnectModalAccordionData(uri: string): AccordionData[] {
+ return [
+ {
+ id: "scan-to-connect",
+ title: "Scan to connect",
+ description: (
+ <>
+
+ {"Scan the QR code below with Pera Wallet's scan feature."}
+
+
+
+ >
+ )
+ },
+ {
+ id: "new-to-pera-wallet",
+ title: "New to Pera Wallet?",
+ description: (
+ <>
+
+ {"Scan the QR code with your phone to download Pera Wallet."}
+
+
+
+ >
+ )
+ }
+ ];
+}
+
+export {getPeraConnectModalAccordionData};
+
export {
PERA_WALLET_CONNECT_MODAL_ID,
PERA_WALLET_REDIRECT_MODAL_ID,
diff --git a/src/modal/section/information/PeraWalletConnectModalInformationSection.tsx b/src/modal/section/information/PeraWalletConnectModalInformationSection.tsx
new file mode 100644
index 0000000..3cbc5d3
--- /dev/null
+++ b/src/modal/section/information/PeraWalletConnectModalInformationSection.tsx
@@ -0,0 +1,95 @@
+import ShieldTickIcon from "../../../asset/icon/ShieldTick.svg";
+import LayerIcon from "../../../asset/icon/Layer.svg";
+import NoteIcon from "../../../asset/icon/Note.svg";
+import PeraWalletWithText from "../../../asset/icon/PeraWallet--with-text.svg";
+
+import "./_pera-wallet-modal-information-section.scss";
+
+import React from "react";
+
+import {useIsSmallScreen} from "../../../util/screen/useMediaQuery";
+import {getPeraWalletAppMeta} from "../../../util/peraWalletUtils";
+
+function PeraWalletConnectModalInformationSection() {
+ const isSmallScreen = useIsSmallScreen();
+ const {logo, name} = getPeraWalletAppMeta();
+
+ return (
+
+
+
+ {isSmallScreen && (
+
+ {`Connect to ${name}`}
+
+ )}
+
+
+ {"Simply the best Algorand wallet."}
+
+
+ {!isSmallScreen && (
+
+ {"Features"}
+
+ )}
+
+
+ -
+
+
+
+
+
+ {"Connect to any Algorand dApp securely"}
+
+
+
+ -
+
+
+
+
+
+ {"Your private keys are safely stored locally"}
+
+
+
+ -
+
+
+
+
+
+ {"View NFTs, buy and swap crypto and more"}
+
+
+
+
+ );
+}
+
+export default PeraWalletConnectModalInformationSection;
diff --git a/src/modal/section/information/_pera-wallet-modal-information-section.scss b/src/modal/section/information/_pera-wallet-modal-information-section.scss
new file mode 100644
index 0000000..f63fb45
--- /dev/null
+++ b/src/modal/section/information/_pera-wallet-modal-information-section.scss
@@ -0,0 +1,102 @@
+@import "../../../ui/styles/media-queries";
+
+.pera-wallet-connect-modal-information-section {
+ padding: 12px;
+ padding-right: 0;
+}
+
+.pera-wallet-connect-modal-information-section__pera-icon {
+ margin-bottom: 32px;
+}
+
+.pera-wallet-connect-modal-information-section__title {
+ margin-bottom: 82px;
+
+ color: #2c3559;
+
+ font-size: 22px;
+ line-height: 30px;
+ letter-spacing: -0.4px;
+ font-weight: 500;
+}
+
+.pera-wallet-connect-modal-information-section__secondary-title {
+ margin-bottom: 16px;
+
+ color: #69708d;
+
+ font-size: 10px;
+ line-height: 20px;
+ letter-spacing: 2px;
+ font-weight: 500;
+ text-transform: uppercase;
+}
+
+.pera-wallet-connect-modal-information-section__features-item {
+ display: grid;
+ align-items: center;
+ grid-template-columns: 36px auto;
+ gap: 16px;
+
+ &:not(:last-of-type) {
+ margin-bottom: 20px;
+ }
+}
+
+.pera-wallet-connect-modal-information-section__features-item__icon-wrapper {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+
+ width: 36px;
+ height: 36px;
+
+ background-color: #ffffff;
+
+ border-radius: 50%;
+}
+
+.pera-wallet-connect-modal-information-section__features-item__description {
+ color: #2c3559;
+
+ font-size: 12px;
+ line-height: 20px;
+ letter-spacing: 0.01px;
+ font-weight: 500;
+}
+
+@include for-small-screens {
+ .pera-wallet-connect-modal-information-section__information-section {
+ padding: 0;
+ }
+
+ .pera-wallet-connect-modal-information-section__pera-icon {
+ margin-bottom: 16px;
+ }
+
+ .pera-wallet-connect-modal-information-section__connect-pera-title {
+ margin-bottom: 8px;
+
+ color: #2c3559;
+
+ font-size: 18px;
+ font-weight: 600;
+ line-height: 22px;
+ letter-spacing: -0.2px;
+ }
+
+ .pera-wallet-connect-modal-information-section__title {
+ margin-bottom: 40px;
+
+ color: #2c3559;
+
+ font-size: 14px;
+ line-height: 24px;
+ letter-spacing: -0.09px;
+ font-weight: 400;
+ }
+
+ .pera-wallet-connect-modal-information-section__features-item__icon-wrapper {
+ background-color: #f2f3f8;
+ }
+}
diff --git a/src/modal/section/pending-message/PeraWalletConnectModalPendingMessage.tsx b/src/modal/section/pending-message/PeraWalletConnectModalPendingMessage.tsx
new file mode 100644
index 0000000..08e4721
--- /dev/null
+++ b/src/modal/section/pending-message/PeraWalletConnectModalPendingMessage.tsx
@@ -0,0 +1,43 @@
+import "./_pera-wallet-connect-modal-pending-message.scss";
+
+import React from "react";
+
+import {getPeraWalletAppMeta} from "../../../util/peraWalletUtils";
+
+interface PeraWalletConnectModalPendingMessageProps {
+ onClose: () => void;
+}
+
+function PeraWalletConnectModalPendingMessage({
+ onClose
+}: PeraWalletConnectModalPendingMessageProps) {
+ const {logo, name} = getPeraWalletAppMeta();
+
+ return (
+ <>
+
+
+
+
+ {`Please wait while we connect you to`}
+
+ {` ${name}...`}
+
+
+
+
+ >
+ );
+
+ function handleCancelClick() {
+ onClose();
+ }
+}
+
+export default PeraWalletConnectModalPendingMessage;
diff --git a/src/modal/section/pending-message/_pera-wallet-connect-modal-pending-message.scss b/src/modal/section/pending-message/_pera-wallet-connect-modal-pending-message.scss
new file mode 100644
index 0000000..edb2d8b
--- /dev/null
+++ b/src/modal/section/pending-message/_pera-wallet-connect-modal-pending-message.scss
@@ -0,0 +1,41 @@
+.pera-wallet-connect-modal-pending-message {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ flex-direction: column;
+
+ text-align: center;
+}
+
+.pera-wallet-connect-modal-pending-message__text {
+ max-width: 271px;
+
+ margin-top: 20px;
+
+ color: #2c3559;
+
+ font-size: 18px;
+ font-weight: 500;
+ line-height: 28px;
+ letter-spacing: -0.26px;
+}
+
+.pera-wallet-connect-modal-pending-message__cancel-button {
+ display: block;
+
+ width: 100%;
+
+ padding: 14px;
+
+ color: #2c3559;
+ background-color: #f2f3f8;
+
+ border-radius: 12px;
+
+ text-decoration: none;
+ text-align: center;
+ font-size: 14px;
+ line-height: 20px;
+ letter-spacing: -0.09px;
+ font-weight: 500;
+}
diff --git a/src/ui/styles/_media-queries.scss b/src/ui/styles/_media-queries.scss
new file mode 100644
index 0000000..687ab56
--- /dev/null
+++ b/src/ui/styles/_media-queries.scss
@@ -0,0 +1,8 @@
+$small-max-width: 767px;
+$small-screen-query: "(max-width: " + $small-max-width + ")";
+
+@mixin for-small-screens {
+ @media #{$small-screen-query} {
+ @content;
+ }
+}
diff --git a/src/util/screen/mediaQueryHookConstants.ts b/src/util/screen/mediaQueryHookConstants.ts
new file mode 100644
index 0000000..912fde4
--- /dev/null
+++ b/src/util/screen/mediaQueryHookConstants.ts
@@ -0,0 +1,7 @@
+import {SMALL_SCREEN_BREAKPOINT} from "./screenSizeConstants";
+
+const MEDIA_QUERIES = {
+ SMALL: `(max-width: ${SMALL_SCREEN_BREAKPOINT}px)`
+};
+
+export {MEDIA_QUERIES};
diff --git a/src/util/screen/useMediaQuery.ts b/src/util/screen/useMediaQuery.ts
new file mode 100644
index 0000000..f3ec4dc
--- /dev/null
+++ b/src/util/screen/useMediaQuery.ts
@@ -0,0 +1,45 @@
+import {useState, useEffect} from "react";
+
+import {MEDIA_QUERIES} from "./mediaQueryHookConstants";
+
+// Originated from : https://github.com/beautifulinteractions/beautiful-react-hooks/blob/master/src/useMediaQuery.js
+
+function useMediaQuery(mediaQuery: string) {
+ const isMatchMediaAPISupported = "matchMedia" in window;
+ const [isMediaMatchingQuery, setIsMediaMatchingQuery] = useState(
+ isMatchMediaAPISupported && Boolean(window.matchMedia(mediaQuery).matches)
+ );
+
+ useEffect(() => {
+ let mediaQueryList: MediaQueryList;
+ let mediaQueryListEventHandler: VoidFunction;
+
+ if (isMatchMediaAPISupported) {
+ mediaQueryList = window.matchMedia(mediaQuery);
+ mediaQueryListEventHandler = function () {
+ setIsMediaMatchingQuery(Boolean(mediaQueryList.matches));
+ };
+
+ if (mediaQueryList) {
+ // Although addListener() is marked as deprecated, it is used here for backward compatibility (for example Safari 13)
+ mediaQueryList.addListener(mediaQueryListEventHandler);
+ }
+ }
+
+ return () => {
+ if (isMatchMediaAPISupported && mediaQueryListEventHandler && mediaQueryList) {
+ // Although removeListener() is marked as deprecated, it is used here for backward compatibility (for example Safari 13)
+ mediaQueryList.removeListener(mediaQueryListEventHandler);
+ }
+ };
+ }, [mediaQuery, isMatchMediaAPISupported]);
+
+ return isMediaMatchingQuery;
+}
+
+function useIsSmallScreen() {
+ return useMediaQuery(MEDIA_QUERIES.SMALL);
+}
+
+export default useMediaQuery;
+export {useIsSmallScreen};
diff --git a/src/util/screen/useOnWindowResize.tsx b/src/util/screen/useOnWindowResize.tsx
new file mode 100644
index 0000000..df85043
--- /dev/null
+++ b/src/util/screen/useOnWindowResize.tsx
@@ -0,0 +1,37 @@
+import {useEffect, useRef} from "react";
+
+const DEFAULT_DEBOUNCE_TIME = 150;
+
+const DEFAULT_OPTIONS = {
+ /* Discard emitted resize events that take less than the specified time */
+ debounceTime: DEFAULT_DEBOUNCE_TIME
+};
+
+function useOnWindowResize(callback: VoidFunction, options = DEFAULT_OPTIONS) {
+ const timeoutId = useRef
(undefined);
+ const callbackRef = useRef(callback);
+
+ useEffect(() => {
+ callbackRef.current = callback;
+ }, [callback]);
+
+ useEffect(() => {
+ window.addEventListener("resize", handleResize);
+
+ return () => {
+ window.removeEventListener("resize", handleResize);
+ clearTimeout(timeoutId.current);
+ };
+
+ function handleResize() {
+ if (!timeoutId.current) {
+ timeoutId.current = setTimeout(() => {
+ callbackRef.current();
+ timeoutId.current = undefined;
+ }, options.debounceTime);
+ }
+ }
+ }, [options.debounceTime]);
+}
+
+export default useOnWindowResize;
diff --git a/src/util/screen/useSetDynamicVhValue.tsx b/src/util/screen/useSetDynamicVhValue.tsx
new file mode 100644
index 0000000..a71077b
--- /dev/null
+++ b/src/util/screen/useSetDynamicVhValue.tsx
@@ -0,0 +1,28 @@
+import {useEffect} from "react";
+
+import useOnWindowResize from "./useOnWindowResize";
+
+/**
+ * Creates a css variable `--vh` that is the calculated viewport height,
+ * and updates it on window resize. This `--vh` value can be used instead of
+ * default `vh` value to prevent layout issues on mobile devices
+ * See: https://css-tricks.com/the-trick-to-viewport-units-on-mobile/
+ */
+function useSetDynamicVhValue() {
+ useEffect(() => {
+ // This useEffect was added to make sure vh is set on mount (even if there is no window resize)
+ setVhVariable();
+ }, []);
+
+ useOnWindowResize(() => {
+ setVhVariable();
+ });
+
+ function setVhVariable() {
+ // a vh unit is equal to 1% of the screen height
+ // eslint-disable-next-line no-magic-numbers
+ document.documentElement.style.setProperty("--vh", `${window.innerHeight * 0.01}px`);
+ }
+}
+
+export default useSetDynamicVhValue;