From 5c2832c9277dcef3b2de546ba78c475b9d66845b Mon Sep 17 00:00:00 2001 From: rob chang Date: Fri, 6 Sep 2024 14:35:07 -0400 Subject: [PATCH 01/11] feat: auth card error states --- .nvmrc | 1 + account-kit/react/.storybook/main.ts | 1 - account-kit/react/.storybook/preview.ts | 1 - account-kit/react/.storybook/preview.tsx | 58 ++++ account-kit/react/package.json | 7 + account-kit/react/public/mockServiceWorker.js | 284 ++++++++++++++++++ .../src/components/auth/card/add-passkey.tsx | 27 +- .../src/components/auth/card/content.tsx | 13 - .../react/src/components/auth/card/eoa.tsx | 1 + .../card/error/connection-error.stories.tsx | 29 ++ .../auth/card/error/connection-error.tsx | 71 +++++ .../auth/card/error/general-error.stories.tsx | 20 ++ .../auth/card/error/general-error.tsx | 16 + .../auth/card/footer/email-not-reveived.tsx | 13 + .../components/auth/card/footer/help-text.tsx | 13 + .../{ => auth/card/footer}/poweredby.tsx | 4 +- .../card/footer/registration-disclaimer.tsx | 11 + .../components/auth/card/index.stories.tsx | 130 ++++++++ .../react/src/components/auth/card/index.tsx | 55 ++-- .../components/auth/card/loading/email.tsx | 20 +- .../components/auth/card/loading/index.tsx | 23 -- .../components/auth/card/loading/passkey.tsx | 2 - .../react/src/components/auth/card/main.tsx | 26 +- .../components/auth/card/passkey-added.tsx | 2 - .../components/auth/card/passkey.stories.tsx | 72 +++++ .../react/src/components/auth/card/steps.tsx | 11 +- .../react/src/components/auth/context.ts | 11 +- .../components/auth/sections/EmailAuth.tsx | 27 +- .../src/components/auth/sections/Footer.tsx | 38 +++ .../react/src/components/button.stories.tsx | 22 +- .../react/src/icons/EOAConnectionFailed.tsx | 140 +++++++++ .../src/icons/passkeyConnectionFailed.tsx | 216 +++++++++++++ account-kit/react/src/icons/warning.tsx | 18 ++ account-kit/react/src/strings.ts | 19 ++ account-kit/react/src/tailwind/theme.ts | 1 + account-kit/react/src/tailwind/types.ts | 1 + account-kit/react/src/tailwind/utils.test.ts | 4 + .../components/preview/AuthCardWrapper.tsx | 2 +- yarn.lock | 253 +++++++++++++++- 39 files changed, 1530 insertions(+), 133 deletions(-) create mode 100644 .nvmrc delete mode 100644 account-kit/react/.storybook/preview.ts create mode 100644 account-kit/react/.storybook/preview.tsx create mode 100644 account-kit/react/public/mockServiceWorker.js create mode 100644 account-kit/react/src/components/auth/card/error/connection-error.stories.tsx create mode 100644 account-kit/react/src/components/auth/card/error/connection-error.tsx create mode 100644 account-kit/react/src/components/auth/card/error/general-error.stories.tsx create mode 100644 account-kit/react/src/components/auth/card/error/general-error.tsx create mode 100644 account-kit/react/src/components/auth/card/footer/email-not-reveived.tsx create mode 100644 account-kit/react/src/components/auth/card/footer/help-text.tsx rename account-kit/react/src/components/{ => auth/card/footer}/poweredby.tsx (70%) create mode 100644 account-kit/react/src/components/auth/card/footer/registration-disclaimer.tsx create mode 100644 account-kit/react/src/components/auth/card/index.stories.tsx delete mode 100644 account-kit/react/src/components/auth/card/loading/index.tsx create mode 100644 account-kit/react/src/components/auth/card/passkey.stories.tsx create mode 100644 account-kit/react/src/components/auth/sections/Footer.tsx create mode 100644 account-kit/react/src/icons/EOAConnectionFailed.tsx create mode 100644 account-kit/react/src/icons/passkeyConnectionFailed.tsx create mode 100644 account-kit/react/src/icons/warning.tsx diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 000000000..2cc859384 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +22.8.0 \ No newline at end of file diff --git a/account-kit/react/.storybook/main.ts b/account-kit/react/.storybook/main.ts index 189ee3500..0e98c3403 100644 --- a/account-kit/react/.storybook/main.ts +++ b/account-kit/react/.storybook/main.ts @@ -1,5 +1,4 @@ import type { StorybookConfig } from "@storybook/react-vite"; - import react from "@vitejs/plugin-react"; import { mergeConfig } from "vite"; diff --git a/account-kit/react/.storybook/preview.ts b/account-kit/react/.storybook/preview.ts deleted file mode 100644 index d3349be43..000000000 --- a/account-kit/react/.storybook/preview.ts +++ /dev/null @@ -1 +0,0 @@ -import "./tailwind.css"; diff --git a/account-kit/react/.storybook/preview.tsx b/account-kit/react/.storybook/preview.tsx new file mode 100644 index 000000000..b874f2b01 --- /dev/null +++ b/account-kit/react/.storybook/preview.tsx @@ -0,0 +1,58 @@ +import "./tailwind.css"; + +import type { Preview } from "@storybook/react"; +import { initialize, mswLoader } from "msw-storybook-addon"; +import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; +import { AlchemyAccountProvider, createConfig } from "../src"; +import React, { useEffect } from "react"; +import { sepolia } from "@account-kit/infra"; + +const queryClient = new QueryClient(); + +initialize(); + +const config = createConfig( + { + rpcUrl: "/api/rpc", + chain: sepolia, + ssr: true, + }, + { + illustrationStyle: "outline", + auth: { + sections: [[{ type: "email" as const }], [{ type: "passkey" as const }]], + addPasskeyOnSignup: true, + }, + } +); + +const preview: Preview = { + decorators: [ + (Story, { args }) => { + // Sync CSS variables + useEffect(() => { + const root = document.querySelector(":root") as HTMLElement; + if (args.isLight === false) { + root.classList.remove("light"); + root.classList.add("dark"); + } else { + root.classList.remove("dark"); + root.classList.add("light"); + } + }, [args]); + return ( + + + + + + ); + }, + ], + args: { + isLight: true, + }, + loaders: [mswLoader], +}; + +export default preview; diff --git a/account-kit/react/package.json b/account-kit/react/package.json index b4d725488..909e460a7 100644 --- a/account-kit/react/package.json +++ b/account-kit/react/package.json @@ -56,6 +56,8 @@ "@storybook/testing-library": "^0.2.2", "@tanstack/react-query": "^5.28.9", "autoprefixer": "^10.4.20", + "msw": "^2.4.4", + "msw-storybook-addon": "^2.0.3", "postcss": "^8.4.45", "react": "^18.2.0", "react-dom": "^18.2.0", @@ -101,5 +103,10 @@ "gitHead": "ee46e8bb857de3b631044fa70714ea706d9e317d", "optionalDependencies": { "alchemy-sdk": "^3.0.0" + }, + "msw": { + "workerDirectory": [ + "public" + ] } } diff --git a/account-kit/react/public/mockServiceWorker.js b/account-kit/react/public/mockServiceWorker.js new file mode 100644 index 000000000..4725e55aa --- /dev/null +++ b/account-kit/react/public/mockServiceWorker.js @@ -0,0 +1,284 @@ +/* eslint-disable */ +/* tslint:disable */ + +/** + * Mock Service Worker. + * @see https://github.com/mswjs/msw + * - Please do NOT modify this file. + * - Please do NOT serve this file on production. + */ + +const PACKAGE_VERSION = "2.4.4"; +const INTEGRITY_CHECKSUM = "26357c79639bfa20d64c0efca2a87423"; +const IS_MOCKED_RESPONSE = Symbol("isMockedResponse"); +const activeClientIds = new Set(); + +self.addEventListener("install", function () { + self.skipWaiting(); +}); + +self.addEventListener("activate", function (event) { + event.waitUntil(self.clients.claim()); +}); + +self.addEventListener("message", async function (event) { + const clientId = event.source.id; + + if (!clientId || !self.clients) { + return; + } + + const client = await self.clients.get(clientId); + + if (!client) { + return; + } + + const allClients = await self.clients.matchAll({ + type: "window", + }); + + switch (event.data) { + case "KEEPALIVE_REQUEST": { + sendToClient(client, { + type: "KEEPALIVE_RESPONSE", + }); + break; + } + + case "INTEGRITY_CHECK_REQUEST": { + sendToClient(client, { + type: "INTEGRITY_CHECK_RESPONSE", + payload: { + packageVersion: PACKAGE_VERSION, + checksum: INTEGRITY_CHECKSUM, + }, + }); + break; + } + + case "MOCK_ACTIVATE": { + activeClientIds.add(clientId); + + sendToClient(client, { + type: "MOCKING_ENABLED", + payload: true, + }); + break; + } + + case "MOCK_DEACTIVATE": { + activeClientIds.delete(clientId); + break; + } + + case "CLIENT_CLOSED": { + activeClientIds.delete(clientId); + + const remainingClients = allClients.filter((client) => { + return client.id !== clientId; + }); + + // Unregister itself when there are no more clients + if (remainingClients.length === 0) { + self.registration.unregister(); + } + + break; + } + } +}); + +self.addEventListener("fetch", function (event) { + const { request } = event; + + // Bypass navigation requests. + if (request.mode === "navigate") { + return; + } + + // Opening the DevTools triggers the "only-if-cached" request + // that cannot be handled by the worker. Bypass such requests. + if (request.cache === "only-if-cached" && request.mode !== "same-origin") { + return; + } + + // Bypass all requests when there are no active clients. + // Prevents the self-unregistered worked from handling requests + // after it's been deleted (still remains active until the next reload). + if (activeClientIds.size === 0) { + return; + } + + // Generate unique request ID. + const requestId = crypto.randomUUID(); + event.respondWith(handleRequest(event, requestId)); +}); + +async function handleRequest(event, requestId) { + const client = await resolveMainClient(event); + const response = await getResponse(event, client, requestId); + + // Send back the response clone for the "response:*" life-cycle events. + // Ensure MSW is active and ready to handle the message, otherwise + // this message will pend indefinitely. + if (client && activeClientIds.has(client.id)) { + (async function () { + const responseClone = response.clone(); + + sendToClient( + client, + { + type: "RESPONSE", + payload: { + requestId, + isMockedResponse: IS_MOCKED_RESPONSE in response, + type: responseClone.type, + status: responseClone.status, + statusText: responseClone.statusText, + body: responseClone.body, + headers: Object.fromEntries(responseClone.headers.entries()), + }, + }, + [responseClone.body] + ); + })(); + } + + return response; +} + +// Resolve the main client for the given event. +// Client that issues a request doesn't necessarily equal the client +// that registered the worker. It's with the latter the worker should +// communicate with during the response resolving phase. +async function resolveMainClient(event) { + const client = await self.clients.get(event.clientId); + + if (client?.frameType === "top-level") { + return client; + } + + const allClients = await self.clients.matchAll({ + type: "window", + }); + + return allClients + .filter((client) => { + // Get only those clients that are currently visible. + return client.visibilityState === "visible"; + }) + .find((client) => { + // Find the client ID that's recorded in the + // set of clients that have registered the worker. + return activeClientIds.has(client.id); + }); +} + +async function getResponse(event, client, requestId) { + const { request } = event; + + // Clone the request because it might've been already used + // (i.e. its body has been read and sent to the client). + const requestClone = request.clone(); + + function passthrough() { + const headers = Object.fromEntries(requestClone.headers.entries()); + + // Remove internal MSW request header so the passthrough request + // complies with any potential CORS preflight checks on the server. + // Some servers forbid unknown request headers. + delete headers["x-msw-intention"]; + + return fetch(requestClone, { headers }); + } + + // Bypass mocking when the client is not active. + if (!client) { + return passthrough(); + } + + // Bypass initial page load requests (i.e. static assets). + // The absence of the immediate/parent client in the map of the active clients + // means that MSW hasn't dispatched the "MOCK_ACTIVATE" event yet + // and is not ready to handle requests. + if (!activeClientIds.has(client.id)) { + return passthrough(); + } + + // Notify the client that a request has been intercepted. + const requestBuffer = await request.arrayBuffer(); + const clientMessage = await sendToClient( + client, + { + type: "REQUEST", + payload: { + id: requestId, + url: request.url, + mode: request.mode, + method: request.method, + headers: Object.fromEntries(request.headers.entries()), + cache: request.cache, + credentials: request.credentials, + destination: request.destination, + integrity: request.integrity, + redirect: request.redirect, + referrer: request.referrer, + referrerPolicy: request.referrerPolicy, + body: requestBuffer, + keepalive: request.keepalive, + }, + }, + [requestBuffer] + ); + + switch (clientMessage.type) { + case "MOCK_RESPONSE": { + return respondWithMock(clientMessage.data); + } + + case "PASSTHROUGH": { + return passthrough(); + } + } + + return passthrough(); +} + +function sendToClient(client, message, transferrables = []) { + return new Promise((resolve, reject) => { + const channel = new MessageChannel(); + + channel.port1.onmessage = (event) => { + if (event.data && event.data.error) { + return reject(event.data.error); + } + + resolve(event.data); + }; + + client.postMessage( + message, + [channel.port2].concat(transferrables.filter(Boolean)) + ); + }); +} + +async function respondWithMock(response) { + // Setting response status code to 0 is a no-op. + // However, when responding with a "Response.error()", the produced Response + // instance will have status code set to 0. Since it's not possible to create + // a Response instance with status code 0, handle that use-case separately. + if (response.status === 0) { + return Response.error(); + } + + const mockedResponse = new Response(response.body, response); + + Reflect.defineProperty(mockedResponse, IS_MOCKED_RESPONSE, { + value: true, + enumerable: true, + }); + + return mockedResponse; +} diff --git a/account-kit/react/src/components/auth/card/add-passkey.tsx b/account-kit/react/src/components/auth/card/add-passkey.tsx index f458a860a..1e0929a1f 100644 --- a/account-kit/react/src/components/auth/card/add-passkey.tsx +++ b/account-kit/react/src/components/auth/card/add-passkey.tsx @@ -6,8 +6,8 @@ import { } from "../../../icons/illustrations/passkeys.js"; import { ls } from "../../../strings.js"; import { Button } from "../../button.js"; -import { PoweredBy } from "../../poweredby.js"; -import { useAuthContext } from "../context.js"; +import { useAuthContext, type AuthStep } from "../context.js"; +import { ConnectionError } from "./error/connection-error.js"; const BENEFITS = [ { @@ -22,15 +22,35 @@ const BENEFITS = [ }, ]; +type AddPasskeyProps = { + authStep: Extract; +}; + // eslint-disable-next-line jsdoc/require-jsdoc -export const AddPasskey = () => { +export const AddPasskey = ({ authStep }: AddPasskeyProps) => { const { setAuthStep } = useAuthContext(); const { addPasskey, isAddingPasskey } = useAddPasskey({ onSuccess: () => { setAuthStep({ type: "passkey_create_success" }); }, + onError: () => { + setAuthStep({ + type: "passkey_create", + error: new Error("Failed to add passkey"), + }); + }, }); + if (authStep.error) { + return ( + setAuthStep({ type: "complete" })} + /> + ); + } + return (
@@ -69,7 +89,6 @@ export const AddPasskey = () => { {ls.addPasskey.skip}
-
); }; diff --git a/account-kit/react/src/components/auth/card/content.tsx b/account-kit/react/src/components/auth/card/content.tsx index b6bc820a1..f5c820300 100644 --- a/account-kit/react/src/components/auth/card/content.tsx +++ b/account-kit/react/src/components/auth/card/content.tsx @@ -1,14 +1,9 @@ import type { ReactNode } from "react"; -import { PoweredBy } from "../../poweredby.js"; interface CardContentProps { header: ReactNode | string; icon?: ReactNode; description: ReactNode | string; - support?: { - text: string; - cta: ReactNode; - }; error?: Error | string; className?: string; } @@ -18,7 +13,6 @@ export const CardContent = ({ header, icon, description, - support, className, }: CardContentProps) => { return ( @@ -36,13 +30,6 @@ export const CardContent = ({ ) : ( description )} - {support && ( -
- {support.text} - {support.cta} -
- )} - ); }; diff --git a/account-kit/react/src/components/auth/card/eoa.tsx b/account-kit/react/src/components/auth/card/eoa.tsx index 3dc847b0d..f2bb53155 100644 --- a/account-kit/react/src/components/auth/card/eoa.tsx +++ b/account-kit/react/src/components/auth/card/eoa.tsx @@ -38,6 +38,7 @@ type WalletConnectCardProps = { }; export const WalletConnectCard = ({ authStep }: WalletConnectCardProps) => { + // If error render the error card here? return ( = { + title: "Errors/ConnectionError", + component: ConnectionError, + args: { + connectionType: "passkey", + walletType: "Coinbase Wallet", + }, + argTypes: { + connectionType: { + control: { + type: "radio", + defaultValue: "passkey", + options: ["passkey", "wallet"], + }, + }, + walletType: { + control: { + type: "radio", + options: ["Coinbase Wallet", "MetaMask", "WalletConnect"], + }, + }, + }, +}; +export default meta; +type Story = StoryObj; +export const Default: Story = {}; diff --git a/account-kit/react/src/components/auth/card/error/connection-error.tsx b/account-kit/react/src/components/auth/card/error/connection-error.tsx new file mode 100644 index 000000000..9b56e2b6c --- /dev/null +++ b/account-kit/react/src/components/auth/card/error/connection-error.tsx @@ -0,0 +1,71 @@ +import { useMemo } from "react"; +import { ls } from "../../../../strings.js"; +import { Button } from "../../../button.js"; +import { PasskeyConnectionFailed } from "../../../../icons/passkeyConnectionFailed.js"; +import { EOAConnectionFailed } from "../../../../icons/EOAConnectionFailed.js"; + +type ConnectionErrorProps = { + connectionType: "passkey" | "wallet" | "timeout"; + walletType?: "Coinbase Wallet" | "MetaMask" | "WalletConnect"; + handleTryAgain?: () => void; + handleUseAnotherMethod?: () => void; +}; + +export const ConnectionError = ({ + connectionType, + walletType, + handleTryAgain, + handleUseAnotherMethod, +}: ConnectionErrorProps) => { + const getHeadingText = useMemo(() => { + switch (connectionType) { + case "passkey": + return ls.error.connection.passkeyTitle; + case "wallet": + return ls.error.connection.walletTitle + walletType; + case "timeout": + return ls.error.connection.timedOutTitle; + } + }, [connectionType, walletType]); + + const getBodyText = useMemo(() => { + switch (connectionType) { + case "passkey": + return ls.error.connection.passkeyBody; + case "wallet": + return ls.error.connection.walletBody; + case "timeout": + return ls.error.connection.timedOutBody; + } + }, [connectionType]); + + const getFailedIcon = useMemo(() => { + switch (connectionType) { + case "passkey": + return ; + case "wallet": + return ; + case "timeout": + return ; + } + }, [connectionType]); + return ( +
+
+
{getFailedIcon}
+
+

{getHeadingText}

+

{getBodyText}

+ + +
+ ); +}; diff --git a/account-kit/react/src/components/auth/card/error/general-error.stories.tsx b/account-kit/react/src/components/auth/card/error/general-error.stories.tsx new file mode 100644 index 000000000..0c59e7117 --- /dev/null +++ b/account-kit/react/src/components/auth/card/error/general-error.stories.tsx @@ -0,0 +1,20 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import { GeneralError } from "./general-error.js"; + +const Container = () => { + return ( +
+
+ +
+
+ ); +}; +const meta: Meta = { + title: "Errors/General Error", + component: Container, +}; +export default meta; + +type Story = StoryObj; +export const Default: Story = {}; diff --git a/account-kit/react/src/components/auth/card/error/general-error.tsx b/account-kit/react/src/components/auth/card/error/general-error.tsx new file mode 100644 index 000000000..4a9c0bbdf --- /dev/null +++ b/account-kit/react/src/components/auth/card/error/general-error.tsx @@ -0,0 +1,16 @@ +import { Warning } from "../../../../icons/warning.js"; +import { ls } from "../../../../strings.js"; + +export const GeneralError = () => { + return ( +
+ +
+

+ {ls.error.general.title} +

+

{ls.error.general.body}

+
+
+ ); +}; diff --git a/account-kit/react/src/components/auth/card/footer/email-not-reveived.tsx b/account-kit/react/src/components/auth/card/footer/email-not-reveived.tsx new file mode 100644 index 000000000..66cf0087e --- /dev/null +++ b/account-kit/react/src/components/auth/card/footer/email-not-reveived.tsx @@ -0,0 +1,13 @@ +import { ls } from "../../../../strings.js"; + +export const EmailNotReceivedDisclaimer = () => ( +
+ + {ls.loadingEmail.emailNotReceived} + + {/* eslint-disable-next-line jsx-a11y/anchor-is-valid */} + + {ls.loadingEmail.resend} + +
+); diff --git a/account-kit/react/src/components/auth/card/footer/help-text.tsx b/account-kit/react/src/components/auth/card/footer/help-text.tsx new file mode 100644 index 000000000..bd2c68ddc --- /dev/null +++ b/account-kit/react/src/components/auth/card/footer/help-text.tsx @@ -0,0 +1,13 @@ +import { ls } from "../../../../strings.js"; + +export const HelpText = () => ( +
+ + {ls.loadingPasskey.supportText} + + {/* eslint-disable-next-line jsx-a11y/anchor-is-valid */} + + {ls.loadingPasskey.supportLink} + +
+); diff --git a/account-kit/react/src/components/poweredby.tsx b/account-kit/react/src/components/auth/card/footer/poweredby.tsx similarity index 70% rename from account-kit/react/src/components/poweredby.tsx rename to account-kit/react/src/components/auth/card/footer/poweredby.tsx index ee71cc0b0..c4eb157a9 100644 --- a/account-kit/react/src/components/poweredby.tsx +++ b/account-kit/react/src/components/auth/card/footer/poweredby.tsx @@ -1,5 +1,5 @@ -import { AlchemyLogo } from "../icons/alchemy.js"; -import { ls } from "../strings.js"; +import { AlchemyLogo } from "../../../../icons/alchemy.js"; +import { ls } from "../../../../strings.js"; // eslint-disable-next-line jsdoc/require-jsdoc export const PoweredBy = () => ( diff --git a/account-kit/react/src/components/auth/card/footer/registration-disclaimer.tsx b/account-kit/react/src/components/auth/card/footer/registration-disclaimer.tsx new file mode 100644 index 000000000..f5e36a6e4 --- /dev/null +++ b/account-kit/react/src/components/auth/card/footer/registration-disclaimer.tsx @@ -0,0 +1,11 @@ +import { ls } from "../../../../strings.js"; + +export const RegistrationDisclaimer = () => ( +
+ {ls.login.tosPrefix} + {/* eslint-disable-next-line jsx-a11y/anchor-is-valid */} + + {ls.login.tosLink} + +
+); diff --git a/account-kit/react/src/components/auth/card/index.stories.tsx b/account-kit/react/src/components/auth/card/index.stories.tsx new file mode 100644 index 000000000..a40f93632 --- /dev/null +++ b/account-kit/react/src/components/auth/card/index.stories.tsx @@ -0,0 +1,130 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import { AuthCard } from "./index.jsx"; +import { useUiConfig } from "../../../hooks/useUiConfig.js"; +import type { AuthType } from "../types.js"; +import { useEffect } from "react"; +import { http, HttpResponse } from "msw"; +const Test = (props: any) => { + const { updateConfig } = useUiConfig(); + let sections: AuthType[][] = [ + [{ type: "email" as const }], + [{ type: "passkey" as const }], + ]; + if (props.authType === "email") { + sections = [[{ type: "email" as const }]]; + } + if (props.authType === "passkey") { + sections = [[{ type: "passkey" as const }]]; + } + if (props.authType === "email-passkey") { + sections = [[{ type: "email" as const }], [{ type: "passkey" as const }]]; + } + if (props.authType === "external_wallets") { + sections = [ + [ + { + type: "external_wallets", + walletConnect: { + projectId: "30e7ffaff99063e68cc9870c105d905b", + }, + }, + ], + ]; + } + + const ui = { + theme: "dark", + primaryColor: { + light: "red", + dark: "#9AB7FF", + }, + borderRadius: "sm", + illustrationStyle: "outline", + logoLight: undefined, + logoDark: undefined, + }; + useEffect(() => { + const uiConfig = { + auth: { + showEmail: true, + showExternalWallets: false, + showPasskey: true, + addPasskey: true, + sections, + }, + ui, + }; + + updateConfig(uiConfig); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [props.authType]); + + return ( +
+ +
+ ); +}; + +const meta: Meta = { + title: "AuthCard", + component: Test, + argTypes: { + authType: { + options: ["email", "passkey", "email-passkey", "external_wallets", "all"], + control: { type: "radio" }, + }, + }, + args: { + authType: "email-passkey", + }, + parameters: { + msw: { + handlers: [ + http.post("/api/rpc/signer/v1/lookup", () => { + return HttpResponse.json({ + orgId: "483c1263-a6e3-4db1-a8b0-894e4902e404", + }); + }), + ], + }, + }, +}; +export default meta; + +type Story = StoryObj; +export const Default: Story = { + args: { + authType: "email", + }, +}; + +export const withLookupError: Story = { + parameters: { + msw: { + handlers: [ + http.post("/api/rpc/signer/v1/lookup", () => { + return new HttpResponse(null, { + status: 500, + statusText: "MSW server error from Storybook", + }); + }), + ], + }, + }, +}; + +export const withSignupError: Story = { + parameters: { + msw: { + handlers: [ + http.post("/api/rpc/signer/v1/signup", () => { + return new HttpResponse(null, { + status: 500, + statusText: "MSW server error from Storybook", + }); + }), + ], + }, + }, +}; diff --git a/account-kit/react/src/components/auth/card/index.tsx b/account-kit/react/src/components/auth/card/index.tsx index 62b809b99..35751e7c7 100644 --- a/account-kit/react/src/components/auth/card/index.tsx +++ b/account-kit/react/src/components/auth/card/index.tsx @@ -1,8 +1,6 @@ "use client"; import { useCallback, useLayoutEffect, useMemo, useRef } from "react"; -import { BaseError } from "viem"; -import { useAuthError } from "../../../hooks/useAuthError.js"; import { useAuthModal } from "../../../hooks/useAuthModal.js"; import { useElementHeight } from "../../../hooks/useElementHeight.js"; import { useSigner } from "../../../hooks/useSigner.js"; @@ -10,9 +8,9 @@ import { useSignerStatus } from "../../../hooks/useSignerStatus.js"; import { useUiConfig } from "../../../hooks/useUiConfig.js"; import { IS_SIGNUP_QP } from "../../constants.js"; import { Navigation } from "../../navigation.js"; -import { Notification } from "../../notification.js"; import { useAuthContext } from "../context.js"; import { Step } from "./steps.js"; +import { Footer } from "../sections/Footer.js"; export type AuthCardProps = { className?: string; @@ -58,7 +56,6 @@ export const AuthCardContent = ({ const { authStep, setAuthStep } = useAuthContext(); const signer = useSigner(); - const error = useAuthError(); const contentRef = useRef(null); const { height } = useElementHeight(contentRef); @@ -66,13 +63,14 @@ export const AuthCardContent = ({ const didGoBack = useRef(false); const { - auth: { hideError, onAuthSuccess }, + auth: { onAuthSuccess }, } = useUiConfig(); const canGoBack = useMemo(() => { return [ "email_verify", "passkey_verify", + "passkey_create", "pick_eoa", "wallet_connect", "eoa_connect", @@ -83,6 +81,7 @@ export const AuthCardContent = ({ switch (authStep.type) { case "email_verify": case "passkey_verify": + case "passkey_create": signer?.disconnect(); // Terminate any inflight authentication didGoBack.current = true; setAuthStep({ type: "initial" }); @@ -126,40 +125,28 @@ export const AuthCardContent = ({ return (
-
- {!hideError && error && error.message && ( - - )} -
- {/* Wrapper container that sizes its height dynamically */}
-
- {(canGoBack || showClose) && ( - - )} - +
+
+ {(canGoBack || showClose) && ( + + )} + +
+
diff --git a/account-kit/react/src/components/auth/card/loading/email.tsx b/account-kit/react/src/components/auth/card/loading/email.tsx index c74e1e49b..21f0d1a17 100644 --- a/account-kit/react/src/components/auth/card/loading/email.tsx +++ b/account-kit/react/src/components/auth/card/loading/email.tsx @@ -2,18 +2,17 @@ import { useEffect, useState } from "react"; import { useAuthenticate } from "../../../../hooks/useAuthenticate.js"; import { useSignerStatus } from "../../../../hooks/useSignerStatus.js"; import { Button } from "../../../button.js"; -import { PoweredBy } from "../../../poweredby.js"; import { useAuthContext, type AuthStep } from "../../context.js"; import { Spinner } from "../../../../icons/spinner.js"; import { ls } from "../../../../strings.js"; import { EmailIllustration } from "../../../../icons/illustrations/email.js"; interface LoadingEmailProps { - context: Extract; + authStep: Extract; } // eslint-disable-next-line jsdoc/require-jsdoc -export const LoadingEmail = ({ context }: LoadingEmailProps) => { +export const LoadingEmail = ({ authStep }: LoadingEmailProps) => { // yup, re-sent and resent. I'm not fixing it const [emailResent, setEmailResent] = useState(false); @@ -43,7 +42,7 @@ export const LoadingEmail = ({ context }: LoadingEmailProps) => {

{ls.loadingEmail.verificationSent}
- {context.email} + {authStep.email}

@@ -58,7 +57,7 @@ export const LoadingEmail = ({ context }: LoadingEmailProps) => { onClick={() => { authenticate({ type: "email", - email: context.email, + email: authStep.email, }); setEmailResent(true); }} @@ -66,28 +65,27 @@ export const LoadingEmail = ({ context }: LoadingEmailProps) => { {emailResent ? ls.loadingEmail.resent : ls.loadingEmail.resend}
-
); }; interface CompletingEmailAuthProps { - context: Extract; + authStep: Extract; } // eslint-disable-next-line jsdoc/require-jsdoc -export const CompletingEmailAuth = ({ context }: CompletingEmailAuthProps) => { +export const CompletingEmailAuth = ({ authStep }: CompletingEmailAuthProps) => { const { isConnected } = useSignerStatus(); const { setAuthStep } = useAuthContext(); useEffect(() => { - if (isConnected && context.createPasskeyAfter) { + if (isConnected && authStep.createPasskeyAfter) { setAuthStep({ type: "passkey_create" }); } else if (isConnected) { setAuthStep({ type: "complete" }); } - }, [context.createPasskeyAfter, isConnected, setAuthStep]); + }, [authStep.createPasskeyAfter, isConnected, setAuthStep]); return (
@@ -98,8 +96,6 @@ export const CompletingEmailAuth = ({ context }: CompletingEmailAuthProps) => {

{ls.completingEmail.body}

- -
); }; diff --git a/account-kit/react/src/components/auth/card/loading/index.tsx b/account-kit/react/src/components/auth/card/loading/index.tsx deleted file mode 100644 index 45ce1f1ad..000000000 --- a/account-kit/react/src/components/auth/card/loading/index.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import type { AuthStep } from "../../context.js"; -import { CompletingEmailAuth, LoadingEmail } from "./email.js"; -import { LoadingPasskeyAuth } from "./passkey.js"; - -type LoadingAuthProps = { - context?: AuthStep; -}; - -// eslint-disable-next-line jsdoc/require-jsdoc -export const LoadingAuth = ({ context }: LoadingAuthProps) => { - switch (context?.type) { - case "email_verify": - return ; - case "passkey_verify": - return ; - case "email_completing": - return ; - default: { - console.warn("Unhandled loading state! rendering empty state", context); - return null; - } - } -}; diff --git a/account-kit/react/src/components/auth/card/loading/passkey.tsx b/account-kit/react/src/components/auth/card/loading/passkey.tsx index 8564affe2..ba6a0c203 100644 --- a/account-kit/react/src/components/auth/card/loading/passkey.tsx +++ b/account-kit/react/src/components/auth/card/loading/passkey.tsx @@ -1,6 +1,5 @@ import { ls } from "../../../../strings.js"; import { LoadingPasskey } from "../../../../icons/passkey.js"; -import { PoweredBy } from "../../../poweredby.js"; // eslint-disable-next-line jsdoc/require-jsdoc export const LoadingPasskeyAuth = () => { @@ -25,7 +24,6 @@ export const LoadingPasskeyAuth = () => { {ls.loadingPasskey.supportLink} */} - ); diff --git a/account-kit/react/src/components/auth/card/main.tsx b/account-kit/react/src/components/auth/card/main.tsx index 0f18cc9f6..35986f0ec 100644 --- a/account-kit/react/src/components/auth/card/main.tsx +++ b/account-kit/react/src/components/auth/card/main.tsx @@ -1,12 +1,17 @@ import { Fragment } from "react"; import { useUiConfig } from "../../../hooks/useUiConfig.js"; -import { ls } from "../../../strings.js"; import { Divider } from "../../divider.js"; -import { PoweredBy } from "../../poweredby.js"; import { AuthSection } from "../sections/AuthSection.js"; +import { GeneralError } from "./error/general-error.js"; +import { type AuthStep } from "../context.js"; + +type MainAuthContentProps = { + authStep: AuthStep; +}; // eslint-disable-next-line jsdoc/require-jsdoc -export const MainAuthContent = () => { +export const MainAuthContent = ({ authStep }: MainAuthContentProps) => { + const isError = authStep.type === "initial" && authStep.error; const { auth: { header, sections, hideSignInText }, } = useUiConfig(); @@ -15,6 +20,7 @@ export const MainAuthContent = () => { <> {header} {!hideSignInText &&

Sign in

} + {isError && } {sections?.map((section, idx) => { return ( @@ -25,20 +31,6 @@ export const MainAuthContent = () => { ); })} -
-

- {`${ls.login.tosPrefix} `} - - {ls.login.tosLink} - -

- -
); }; diff --git a/account-kit/react/src/components/auth/card/passkey-added.tsx b/account-kit/react/src/components/auth/card/passkey-added.tsx index 70c629b33..1a887d7f6 100644 --- a/account-kit/react/src/components/auth/card/passkey-added.tsx +++ b/account-kit/react/src/components/auth/card/passkey-added.tsx @@ -1,5 +1,4 @@ import { AddedPasskeyIllustration } from "../../../icons/illustrations/added-passkey.js"; -import { PoweredBy } from "../../poweredby.js"; // eslint-disable-next-line jsdoc/require-jsdoc export function PasskeyAdded() { @@ -12,7 +11,6 @@ export function PasskeyAdded() {

You can use this passkey to sign in next time.

- ); } diff --git a/account-kit/react/src/components/auth/card/passkey.stories.tsx b/account-kit/react/src/components/auth/card/passkey.stories.tsx new file mode 100644 index 000000000..476054781 --- /dev/null +++ b/account-kit/react/src/components/auth/card/passkey.stories.tsx @@ -0,0 +1,72 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import { AuthCard } from "./index.jsx"; +import { useUiConfig } from "../../../hooks/useUiConfig.js"; +import type { AuthType } from "../types.js"; +import { useEffect } from "react"; +import { http, HttpResponse } from "msw"; +import { useAuthContext } from "../context.js"; + +const PasskeyStory = (props: any) => { + const { updateConfig } = useUiConfig(); + let sections: AuthType[][] = [[{ type: "passkey" as const }]]; + + const ui = { + theme: "dark", + primaryColor: { + light: "red", + dark: "#9AB7FF", + }, + borderRadius: "sm", + illustrationStyle: "outline", + logoLight: undefined, + logoDark: undefined, + }; + + useEffect(() => { + const uiConfig = { + auth: { + showEmail: true, + showExternalWallets: false, + showPasskey: true, + addPasskey: true, + sections, + }, + ui, + }; + + updateConfig(uiConfig); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [props.authType]); + + const { setAuthStep } = useAuthContext(); + useEffect(() => { + setAuthStep({ type: "passkey_create" }); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + return ; +}; + +const meta: Meta = { + title: "Passkey", + component: PasskeyStory, + args: { + authType: "passkey", + }, + + parameters: { + msw: { + handlers: [ + http.post("/api/rpc/signer/v1/lookup", () => { + return HttpResponse.json({ + orgId: "483c1263-a6e3-4db1-a8b0-894e4902e404", + }); + }), + ], + }, + }, +}; +export default meta; + +type Story = StoryObj; +export const Default: Story = {}; diff --git a/account-kit/react/src/components/auth/card/steps.tsx b/account-kit/react/src/components/auth/card/steps.tsx index 70abc9f61..b923e7d1c 100644 --- a/account-kit/react/src/components/auth/card/steps.tsx +++ b/account-kit/react/src/components/auth/card/steps.tsx @@ -1,7 +1,8 @@ import { useAuthContext } from "../context.js"; import { AddPasskey } from "./add-passkey.js"; import { EoaConnectCard, EoaPickCard, WalletConnectCard } from "./eoa.js"; -import { LoadingAuth } from "./loading/index.js"; +import { LoadingEmail, CompletingEmailAuth } from "./loading/email.js"; +import { LoadingPasskeyAuth } from "./loading/passkey.js"; import { MainAuthContent } from "./main.js"; import { PasskeyAdded } from "./passkey-added.js"; @@ -11,11 +12,13 @@ export const Step = () => { switch (authStep.type) { case "email_verify": + return ; case "passkey_verify": + return ; case "email_completing": - return ; + return ; case "passkey_create": - return ; + return ; case "passkey_create_success": return ; case "eoa_connect": @@ -27,6 +30,6 @@ export const Step = () => { case "complete": case "initial": default: - return ; + return ; } }; diff --git a/account-kit/react/src/components/auth/context.ts b/account-kit/react/src/components/auth/context.ts index 645f72252..30c6d2c13 100644 --- a/account-kit/react/src/components/auth/context.ts +++ b/account-kit/react/src/components/auth/context.ts @@ -3,13 +3,19 @@ import type { Connector } from "@wagmi/core"; import { createContext, useContext } from "react"; +// type AuthError = { +// header: string; +// message: string; +// icon: string; +// }; + export type AuthStep = | { type: "email_verify"; email: string } | { type: "passkey_verify"; error?: Error } - | { type: "passkey_create" } + | { type: "passkey_create"; error?: Error } | { type: "passkey_create_success" } | { type: "email_completing"; createPasskeyAfter?: boolean } - | { type: "initial" } + | { type: "initial"; error?: Error } | { type: "complete" } | { type: "eoa_connect"; connector: Connector; error?: Error } | { type: "wallet_connect"; error?: Error } @@ -28,6 +34,7 @@ export const AuthModalContext = createContext( // eslint-disable-next-line jsdoc/require-jsdoc export const useAuthContext = (): AuthContextType => { const context = useContext(AuthModalContext); + if (!context) { throw new Error( "useAuthModalContext must be used within a AuthModalProvider" diff --git a/account-kit/react/src/components/auth/sections/EmailAuth.tsx b/account-kit/react/src/components/auth/sections/EmailAuth.tsx index 1e7c3a233..cafc2a86e 100644 --- a/account-kit/react/src/components/auth/sections/EmailAuth.tsx +++ b/account-kit/react/src/components/auth/sections/EmailAuth.tsx @@ -33,10 +33,8 @@ export const EmailAuth = ({ setAuthStep({ type: "complete" }); }, onError: (error) => { - // TODO: need to handle this and show it to the user console.error(error); - // TODO: need to pass this error along - setAuthStep({ type: "initial" }); + setAuthStep({ type: "initial", error }); }, }); @@ -45,13 +43,24 @@ export const EmailAuth = ({ email: "", }, onSubmit: async ({ value: { email } }) => { - const existingUser = await signer?.getUser(email); - const redirectParams = new URLSearchParams(); - if (existingUser == null) { - redirectParams.set(IS_SIGNUP_QP, "true"); - } + try { + const existingUser = await signer?.getUser(email); + const redirectParams = new URLSearchParams(); + + if (existingUser == null) { + redirectParams.set(IS_SIGNUP_QP, "true"); + } - await authenticateAsync({ type: "email", email, redirectParams }); + await authenticateAsync({ + type: "email", + email, + redirectParams, + }); + } catch (e) { + const error = e instanceof Error ? e : new Error("An Unknown error"); + + setAuthStep({ type: "initial", error }); + } }, validatorAdapter: zodValidator, }); diff --git a/account-kit/react/src/components/auth/sections/Footer.tsx b/account-kit/react/src/components/auth/sections/Footer.tsx new file mode 100644 index 000000000..22df15c55 --- /dev/null +++ b/account-kit/react/src/components/auth/sections/Footer.tsx @@ -0,0 +1,38 @@ +import { EmailNotReceivedDisclaimer } from "../card/footer/email-not-reveived.js"; +import { HelpText } from "../card/footer/help-text.js"; +import { PoweredBy } from "../card/footer/poweredby.js"; +import { RegistrationDisclaimer } from "../card/footer/registration-disclaimer.js"; +import type { AuthStep } from "../context.js"; + +type FooterProps = { + authStep: AuthStep; +}; + +const RenderFooterText = ({ authStep }: FooterProps) => { + switch (authStep.type) { + case "initial": + return ; + case "email_verify": + return ; + case "passkey_create": + case "wallet_connect": + case "passkey_verify": + return ; + case "email_completing": + case "passkey_create_success": + case "eoa_connect": + case "pick_eoa": + case "complete": + return null; + } +}; +export const Footer = ({ authStep }: FooterProps) => { + return ( +
+ +
+ +
+
+ ); +}; diff --git a/account-kit/react/src/components/button.stories.tsx b/account-kit/react/src/components/button.stories.tsx index 08f83b2db..33ba5123a 100644 --- a/account-kit/react/src/components/button.stories.tsx +++ b/account-kit/react/src/components/button.stories.tsx @@ -1,9 +1,29 @@ import type { Meta, StoryObj } from "@storybook/react"; -import { Button } from "./button.js"; +import { Button } from "./button.jsx"; const meta: Meta = { component: Button, title: "Button", + args: { + variant: "primary", + disabled: false, + }, + argTypes: { + variant: { + control: { + type: "radio", + options: ["primary", "secondary", "social"], + }, + }, + disabled: { + control: { + type: "boolean", + }, + }, + onClick: { + action: "clicked", + }, + }, }; export default meta; type Story = StoryObj; diff --git a/account-kit/react/src/icons/EOAConnectionFailed.tsx b/account-kit/react/src/icons/EOAConnectionFailed.tsx new file mode 100644 index 000000000..301bfded0 --- /dev/null +++ b/account-kit/react/src/icons/EOAConnectionFailed.tsx @@ -0,0 +1,140 @@ +export const EOAConnectionFailed = () => { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +}; diff --git a/account-kit/react/src/icons/passkeyConnectionFailed.tsx b/account-kit/react/src/icons/passkeyConnectionFailed.tsx new file mode 100644 index 000000000..be8b61c4e --- /dev/null +++ b/account-kit/react/src/icons/passkeyConnectionFailed.tsx @@ -0,0 +1,216 @@ +export const PasskeyConnectionFailed = () => { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +}; diff --git a/account-kit/react/src/icons/warning.tsx b/account-kit/react/src/icons/warning.tsx new file mode 100644 index 000000000..5b0aca62e --- /dev/null +++ b/account-kit/react/src/icons/warning.tsx @@ -0,0 +1,18 @@ +export const Warning = () => { + return ( + + + + ); +}; diff --git a/account-kit/react/src/strings.ts b/account-kit/react/src/strings.ts index 72dce13ae..d18d066b9 100644 --- a/account-kit/react/src/strings.ts +++ b/account-kit/react/src/strings.ts @@ -42,6 +42,25 @@ const STRINGS = { poweredBy: { title: "powered by", }, + error: { + general: { + title: "Permission denied", + body: "The request is currently not allowed by the agent or the platform. Try again later.", + }, + connection: { + passkeyTitle: "Connection failed", + passkeyBody: + "Passkey request timed out or canceled by the agent. You may have to use another method to register a passkey for your account.", + walletTitle: "Couldn't connect to ", + walletBody: "The wallet’s connection failed or canceled", + timedOutTitle: "Connection timed out", + timedOutBody: "The connection timed out, please try again.", + }, + cta: { + tryAgain: "Try again", + useAnotherMethod: "Use another method", + }, + }, }, }; diff --git a/account-kit/react/src/tailwind/theme.ts b/account-kit/react/src/tailwind/theme.ts index 1c57c1204..d56047c58 100644 --- a/account-kit/react/src/tailwind/theme.ts +++ b/account-kit/react/src/tailwind/theme.ts @@ -35,6 +35,7 @@ export function createDefaultTheme(): AccountKitTheme { "bg-surface-error": createColorSet("#DC2626", "#F87171"), "bg-surface-success": createColorSet("#16A34A", "#86EFAC"), "bg-surface-warning": createColorSet("#EA580C", "#FDBA74"), + "bg-surface-critical-light": createColorSet("#FEE2E2", "#FEE2E2"), }, borderRadius: "sm", }; diff --git a/account-kit/react/src/tailwind/types.ts b/account-kit/react/src/tailwind/types.ts index 0f65307bf..bd8673802 100644 --- a/account-kit/react/src/tailwind/types.ts +++ b/account-kit/react/src/tailwind/types.ts @@ -31,6 +31,7 @@ export interface AccountKitTheme { "bg-surface-success": ColorVariantRecord; "bg-surface-warning": ColorVariantRecord; "bg-surface-error": ColorVariantRecord; + "bg-surface-critical-light": ColorVariantRecord; }; // these define the border radius base for the various components. // the mapped value applies to the smallest value used and everything scales up from there by multiple of 2 diff --git a/account-kit/react/src/tailwind/utils.test.ts b/account-kit/react/src/tailwind/utils.test.ts index 7c1976736..6df3b37a6 100644 --- a/account-kit/react/src/tailwind/utils.test.ts +++ b/account-kit/react/src/tailwind/utils.test.ts @@ -51,6 +51,10 @@ describe("tailwind utils test", () => { "dark": "#FDBA74", "light": "#EA580C", }, + ""bg-surface-critical-light": { + "dark": "#FEF2F2", + "light": "#FEF2F2", + }, "btn-auth": { "dark": "argb(255, 255, 255, 0.05)", "light": "#FFF", diff --git a/examples/ui-demo/src/components/preview/AuthCardWrapper.tsx b/examples/ui-demo/src/components/preview/AuthCardWrapper.tsx index 35b908a7c..6eae1ea6b 100644 --- a/examples/ui-demo/src/components/preview/AuthCardWrapper.tsx +++ b/examples/ui-demo/src/components/preview/AuthCardWrapper.tsx @@ -18,7 +18,7 @@ export function AuthCardWrapper({ className }: { className?: string }) { > {!user ? (
-
+
diff --git a/yarn.lock b/yarn.lock index aa0b43640..d43782205 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2261,6 +2261,28 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== +"@bundled-es-modules/cookie@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@bundled-es-modules/cookie/-/cookie-2.0.0.tgz#c3b82703969a61cf6a46e959a012b2c257f6b164" + integrity sha512-Or6YHg/kamKHpxULAdSqhGqnWFneIXu1NKvvfBBzKGwpVsYuFIQ5aBPHDnnoR3ghW1nvSkALd+EF9iMtY7Vjxw== + dependencies: + cookie "^0.5.0" + +"@bundled-es-modules/statuses@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@bundled-es-modules/statuses/-/statuses-1.0.1.tgz#761d10f44e51a94902c4da48675b71a76cc98872" + integrity sha512-yn7BklA5acgcBr+7w064fGV+SGIFySjCKpqjcWgBAIfrAkY+4GQTJJHQMeT3V/sgz23VTEVV8TtOmkvJAhFVfg== + dependencies: + statuses "^2.0.1" + +"@bundled-es-modules/tough-cookie@^0.1.6": + version "0.1.6" + resolved "https://registry.yarnpkg.com/@bundled-es-modules/tough-cookie/-/tough-cookie-0.1.6.tgz#fa9cd3cedfeecd6783e8b0d378b4a99e52bde5d3" + integrity sha512-dvMHbL464C0zI+Yqxbz6kZ5TOEp7GLW+pry/RWndAR8MJQAXZ2rPmIs8tziTZjeIyhSNZgZbCePtfSbdWqStJw== + dependencies: + "@types/tough-cookie" "^4.0.5" + tough-cookie "^4.1.4" + "@clack/core@^0.3.3": version "0.3.4" resolved "https://registry.yarnpkg.com/@clack/core/-/core-0.3.4.tgz#375e82fc8fe46650b37cab2f2ea8752c6b7f0450" @@ -3469,6 +3491,45 @@ resolved "https://registry.npmjs.org/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz" integrity sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q== +"@inquirer/confirm@^3.0.0": + version "3.2.0" + resolved "https://registry.yarnpkg.com/@inquirer/confirm/-/confirm-3.2.0.tgz#6af1284670ea7c7d95e3f1253684cfbd7228ad6a" + integrity sha512-oOIwPs0Dvq5220Z8lGL/6LHRTEr9TgLHmiI99Rj1PJ1p1czTys+olrgBqZk4E2qC0YTzeHprxSQmoHioVdJ7Lw== + dependencies: + "@inquirer/core" "^9.1.0" + "@inquirer/type" "^1.5.3" + +"@inquirer/core@^9.1.0": + version "9.1.0" + resolved "https://registry.yarnpkg.com/@inquirer/core/-/core-9.1.0.tgz#158b82dc44564a1abd0ce14723d50c3efa0634a2" + integrity sha512-RZVfH//2ytTjmaBIzeKT1zefcQZzuruwkpTwwbe/i2jTl4o9M+iML5ChULzz6iw1Ok8iUBBsRCjY2IEbD8Ft4w== + dependencies: + "@inquirer/figures" "^1.0.5" + "@inquirer/type" "^1.5.3" + "@types/mute-stream" "^0.0.4" + "@types/node" "^22.5.2" + "@types/wrap-ansi" "^3.0.0" + ansi-escapes "^4.3.2" + cli-spinners "^2.9.2" + cli-width "^4.1.0" + mute-stream "^1.0.0" + signal-exit "^4.1.0" + strip-ansi "^6.0.1" + wrap-ansi "^6.2.0" + yoctocolors-cjs "^2.1.2" + +"@inquirer/figures@^1.0.5": + version "1.0.5" + resolved "https://registry.yarnpkg.com/@inquirer/figures/-/figures-1.0.5.tgz#57f9a996d64d3e3345d2a3ca04d36912e94f8790" + integrity sha512-79hP/VWdZ2UVc9bFGJnoQ/lQMpL74mGgzSYX1xUqCVk7/v73vJCMw1VuyWN1jGkZ9B3z7THAbySqGbCNefcjfA== + +"@inquirer/type@^1.5.3": + version "1.5.3" + resolved "https://registry.yarnpkg.com/@inquirer/type/-/type-1.5.3.tgz#220ae9f3d5ae17dd3b2ce5ffd6b48c4a30c73181" + integrity sha512-xUQ14WQGR/HK5ei+2CvgcwoH9fQ4PgPGmVFSN0pc1+fVyDL3MREhyAY7nxEErSu6CkllBM3D7e3e+kOvtu+eIg== + dependencies: + mute-stream "^1.0.0" + "@ioredis/commands@^1.1.1": version "1.2.0" resolved "https://registry.npmjs.org/@ioredis/commands/-/commands-1.2.0.tgz" @@ -4284,6 +4345,18 @@ "@motionone/dom" "^10.16.4" tslib "^2.3.1" +"@mswjs/interceptors@^0.35.0": + version "0.35.0" + resolved "https://registry.yarnpkg.com/@mswjs/interceptors/-/interceptors-0.35.0.tgz#ccdabb668833b97d3c5f26e761f5ea665629dd5f" + integrity sha512-f5cHyIvm4m4g1I5x9EH1etGx0puaU0OaX2szqGRVBVgUC6aMASlOI5hbpe7tJ9l4/VWjCUu5OMraCazLZGI24A== + dependencies: + "@open-draft/deferred-promise" "^2.2.0" + "@open-draft/logger" "^0.3.0" + "@open-draft/until" "^2.0.0" + is-node-process "^1.2.0" + outvariant "^1.4.3" + strict-event-emitter "^0.5.1" + "@next/env@14.1.4": version "14.1.4" resolved "https://registry.yarnpkg.com/@next/env/-/env-14.1.4.tgz#432e80651733fbd67230bf262aee28be65252674" @@ -4892,6 +4965,24 @@ dependencies: "@octokit/openapi-types" "^18.0.0" +"@open-draft/deferred-promise@^2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@open-draft/deferred-promise/-/deferred-promise-2.2.0.tgz#4a822d10f6f0e316be4d67b4d4f8c9a124b073bd" + integrity sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA== + +"@open-draft/logger@^0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@open-draft/logger/-/logger-0.3.0.tgz#2b3ab1242b360aa0adb28b85f5d7da1c133a0954" + integrity sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ== + dependencies: + is-node-process "^1.2.0" + outvariant "^1.4.0" + +"@open-draft/until@^2.0.0", "@open-draft/until@^2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@open-draft/until/-/until-2.1.0.tgz#0acf32f470af2ceaf47f095cdecd40d68666efda" + integrity sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg== + "@parcel/watcher-android-arm64@2.3.0": version "2.3.0" resolved "https://registry.yarnpkg.com/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.3.0.tgz#d82e74bb564ebd4d8a88791d273a3d2bd61e27ab" @@ -6877,6 +6968,11 @@ dependencies: "@types/node" "*" +"@types/cookie@^0.6.0": + version "0.6.0" + resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.6.0.tgz#eac397f28bf1d6ae0ae081363eca2f425bedf0d5" + integrity sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA== + "@types/cross-spawn@^6.0.2": version "6.0.6" resolved "https://registry.yarnpkg.com/@types/cross-spawn/-/cross-spawn-6.0.6.tgz#0163d0b79a6f85409e0decb8dcca17147f81fd22" @@ -7121,6 +7217,13 @@ resolved "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz" integrity sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g== +"@types/mute-stream@^0.0.4": + version "0.0.4" + resolved "https://registry.yarnpkg.com/@types/mute-stream/-/mute-stream-0.0.4.tgz#77208e56a08767af6c5e1237be8888e2f255c478" + integrity sha512-CPM9nzrCPPJHQNA9keH9CVkVI+WR5kMa+7XEs5jcGQ0VoAGnLv242w8lIVgwAEfmE4oufJRaTc9PNLQl0ioAow== + dependencies: + "@types/node" "*" + "@types/node-fetch@^2.6.4": version "2.6.11" resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.11.tgz#9b39b78665dae0e82a08f02f4967d62c66f95d24" @@ -7167,6 +7270,13 @@ dependencies: undici-types "~5.26.4" +"@types/node@^22.5.2": + version "22.5.4" + resolved "https://registry.yarnpkg.com/@types/node/-/node-22.5.4.tgz#83f7d1f65bc2ed223bdbf57c7884f1d5a4fa84e8" + integrity sha512-FDuKUJQm/ju9fT/SeX/6+gBzoPzlVCzfzmGkwKvRHQVxi4BntVbyIwf6a4Xn62mrvndLiml6z/UBXIdEVjQLXg== + dependencies: + undici-types "~6.19.2" + "@types/normalize-package-data@^2.4.0": version "2.4.4" resolved "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz" @@ -7282,11 +7392,21 @@ resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.3.tgz#6209321eb2c1712a7e7466422b8cb1fc0d9dd5d8" integrity sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw== +"@types/statuses@^2.0.4": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@types/statuses/-/statuses-2.0.5.tgz#f61ab46d5352fd73c863a1ea4e1cef3b0b51ae63" + integrity sha512-jmIUGWrAiwu3dZpxntxieC+1n/5c3mjrImkmOSQ2NC5uP6cYO4aAZDdSmRcI5C1oiTmqlZGHC+/NmJrKogbP5A== + "@types/supports-color@^8.0.0": version "8.1.3" resolved "https://registry.yarnpkg.com/@types/supports-color/-/supports-color-8.1.3.tgz#b769cdce1d1bb1a3fa794e35b62c62acdf93c139" integrity sha512-Hy6UMpxhE3j1tLpl27exp1XqHD7n8chAiNPzWfz16LPZoMMoSc4dzLl6w9qijkEb/r5O1ozdu1CWGA2L83ZeZg== +"@types/tough-cookie@^4.0.5": + version "4.0.5" + resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-4.0.5.tgz#cb6e2a691b70cb177c6e3ae9c1d2e8b2ea8cd304" + integrity sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA== + "@types/trusted-types@^2.0.2": version "2.0.7" resolved "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz" @@ -7314,6 +7434,11 @@ dependencies: "@types/node" "*" +"@types/wrap-ansi@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/wrap-ansi/-/wrap-ansi-3.0.0.tgz#18b97a972f94f60a679fd5c796d96421b9abb9fd" + integrity sha512-ltIpx+kM7g/MLRZfkbL7EsCEjfzCcScLpkg37eXEtx5kmrAKBkTJwd1GIAjDSL8wTpM6Hzn5YO4pSb91BEwu1g== + "@types/yargs-parser@*": version "21.0.3" resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.3.tgz#815e30b786d2e8f0dcd85fd5bcf5e1a04d008f15" @@ -8656,7 +8781,7 @@ ansi-colors@^4.1.1: resolved "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz" integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw== -ansi-escapes@^4.2.1: +ansi-escapes@^4.2.1, ansi-escapes@^4.3.2: version "4.3.2" resolved "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz" integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== @@ -9924,6 +10049,11 @@ cli-width@^3.0.0: resolved "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz" integrity sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw== +cli-width@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-4.1.0.tgz#42daac41d3c254ef38ad8ac037672130173691c5" + integrity sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ== + client-only@0.0.1: version "0.0.1" resolved "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz" @@ -10330,6 +10460,11 @@ cookie@0.6.0: resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.6.0.tgz#2798b04b071b0ecbff0dbb62a505a8efa4e19051" integrity sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw== +cookie@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" + integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== + core-js-compat@^3.31.0, core-js-compat@^3.33.1: version "3.34.0" resolved "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.34.0.tgz" @@ -13296,6 +13431,11 @@ graphemer@^1.4.0: resolved "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz" integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== +graphql@^16.8.1: + version "16.9.0" + resolved "https://registry.yarnpkg.com/graphql/-/graphql-16.9.0.tgz#1c310e63f16a49ce1fbb230bd0a000e99f6f115f" + integrity sha512-GGTKBX4SD7Wdb8mqeDLni2oaRGYQWjWHGKPQ24ZMnUtKfcsVoiv4uX8+LJr1K6U5VW2Lu1BwJnj7uiori0YtRw== + h3@^1.8.1, h3@^1.8.2: version "1.9.0" resolved "https://registry.npmjs.org/h3/-/h3-1.9.0.tgz" @@ -13543,6 +13683,11 @@ hastscript@^8.0.0: property-information "^6.0.0" space-separated-tokens "^2.0.0" +headers-polyfill@^4.0.2: + version "4.0.3" + resolved "https://registry.yarnpkg.com/headers-polyfill/-/headers-polyfill-4.0.3.tgz#922a0155de30ecc1f785bcf04be77844ca95ad07" + integrity sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ== + hey-listen@^1.0.8: version "1.0.8" resolved "https://registry.npmjs.org/hey-listen/-/hey-listen-1.0.8.tgz" @@ -14209,6 +14354,11 @@ is-negative-zero@^2.0.2: resolved "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz" integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== +is-node-process@^1.0.1, is-node-process@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/is-node-process/-/is-node-process-1.2.0.tgz#ea02a1b90ddb3934a19aea414e88edef7e11d134" + integrity sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw== + is-number-object@^1.0.4: version "1.0.7" resolved "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz" @@ -17038,6 +17188,36 @@ ms@2.1.3, ms@^2.0.0, ms@^2.1.1: resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== +msw-storybook-addon@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/msw-storybook-addon/-/msw-storybook-addon-2.0.3.tgz#6a9ccf19f89ec9dde1d17e4a3be71d93b42e857a" + integrity sha512-CzHmGO32JeOPnyUnRWnB0PFTXCY1HKfHiEB/6fYoUYiFm2NYosLjzs9aBd3XJUryYEN0avJqMNh7nCRDxE5JjQ== + dependencies: + is-node-process "^1.0.1" + +msw@^2.4.4: + version "2.4.4" + resolved "https://registry.yarnpkg.com/msw/-/msw-2.4.4.tgz#d40c12b2d99750e3b2cbd94ef269a23b06a9aa67" + integrity sha512-iuM0qGs4YmgYCLH+xqb07w2e/e4fYmsx3+WHVlIOUA34TW1sw+wRpNmOlXnLDkw/T7233Jnm6t+aNf4v2E3e2Q== + dependencies: + "@bundled-es-modules/cookie" "^2.0.0" + "@bundled-es-modules/statuses" "^1.0.1" + "@bundled-es-modules/tough-cookie" "^0.1.6" + "@inquirer/confirm" "^3.0.0" + "@mswjs/interceptors" "^0.35.0" + "@open-draft/until" "^2.1.0" + "@types/cookie" "^0.6.0" + "@types/statuses" "^2.0.4" + chalk "^4.1.2" + graphql "^16.8.1" + headers-polyfill "^4.0.2" + is-node-process "^1.2.0" + outvariant "^1.4.2" + path-to-regexp "^6.2.0" + strict-event-emitter "^0.5.1" + type-fest "^4.9.0" + yargs "^17.7.2" + multiformats@^9.4.2: version "9.9.0" resolved "https://registry.npmjs.org/multiformats/-/multiformats-9.9.0.tgz" @@ -17059,7 +17239,7 @@ mute-stream@0.0.8: resolved "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz" integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== -mute-stream@~1.0.0: +mute-stream@^1.0.0, mute-stream@~1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz" integrity sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA== @@ -17902,6 +18082,11 @@ outdent@^0.8.0: resolved "https://registry.npmjs.org/outdent/-/outdent-0.8.0.tgz" integrity sha512-KiOAIsdpUTcAXuykya5fnVVT+/5uS0Q1mrkRHcF89tpieSmY33O/tmc54CqwA+bfhbtEfZUNLHaPUiB9X3jt1A== +outvariant@^1.4.0, outvariant@^1.4.2, outvariant@^1.4.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/outvariant/-/outvariant-1.4.3.tgz#221c1bfc093e8fec7075497e7799fdbf43d14873" + integrity sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA== + p-finally@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz" @@ -18290,6 +18475,11 @@ path-to-regexp@^1.0.0: dependencies: isarray "0.0.1" +path-to-regexp@^6.2.0: + version "6.2.2" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-6.2.2.tgz#324377a83e5049cbecadc5554d6a63a9a4866b36" + integrity sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw== + path-type@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz" @@ -18795,6 +18985,11 @@ proxy-from-env@^1.1.0: resolved "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz" integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== +psl@^1.1.33: + version "1.9.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7" + integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag== + pump@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz" @@ -18803,7 +18998,7 @@ pump@^3.0.0: end-of-stream "^1.1.0" once "^1.3.1" -punycode@^2.1.0: +punycode@^2.1.0, punycode@^2.1.1: version "2.3.1" resolved "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz" integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== @@ -18859,6 +19054,11 @@ query-string@7.1.3: split-on-first "^1.0.0" strict-uri-encode "^2.0.0" +querystringify@^2.1.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6" + integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ== + queue-microtask@^1.2.2: version "1.2.3" resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz" @@ -20259,7 +20459,7 @@ stat-mode@0.3.0: resolved "https://registry.yarnpkg.com/stat-mode/-/stat-mode-0.3.0.tgz#69283b081f851582b328d2a4ace5f591ce52f54b" integrity sha512-QjMLR0A3WwFY2aZdV0okfFEJB5TRjkggXZjxP3A1RsWsNHNu3YPv8btmtc6iCFZ0Rul3FE93OYogvhOUClU+ng== -statuses@2.0.1: +statuses@2.0.1, statuses@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== @@ -20358,6 +20558,11 @@ streamsearch@^1.1.0: resolved "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz" integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg== +strict-event-emitter@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/strict-event-emitter/-/strict-event-emitter-0.5.1.tgz#1602ece81c51574ca39c6815e09f1a3e8550bd93" + integrity sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ== + strict-uri-encode@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz" @@ -21041,6 +21246,16 @@ toml@^3.0.0: resolved "https://registry.yarnpkg.com/toml/-/toml-3.0.0.tgz#342160f1af1904ec9d204d03a5d61222d762c5ee" integrity sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w== +tough-cookie@^4.1.4: + version "4.1.4" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.4.tgz#945f1461b45b5a8c76821c33ea49c3ac192c1b36" + integrity sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag== + dependencies: + psl "^1.1.33" + punycode "^2.1.1" + universalify "^0.2.0" + url-parse "^1.5.3" + tr46@~0.0.3: version "0.0.3" resolved "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz" @@ -21271,6 +21486,11 @@ type-fest@^3.8.0: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-3.13.1.tgz#bb744c1f0678bea7543a2d1ec24e83e68e8c8706" integrity sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g== +type-fest@^4.9.0: + version "4.26.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-4.26.1.tgz#a4a17fa314f976dd3e6d6675ef6c775c16d7955e" + integrity sha512-yOGpmOAL7CkKe/91I5O3gPICmJNLJ1G4zFYVAsRHg7M64biSnPtRj0WNQt++bRkjYOqjWXrhnUw1utzmVErAdg== + type-is@~1.6.18: version "1.6.18" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" @@ -21409,6 +21629,11 @@ undici-types@~5.26.4: resolved "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz" integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== +undici-types@~6.19.2: + version "6.19.8" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.19.8.tgz#35111c9d1437ab83a7cdc0abae2f26d88eda0a02" + integrity sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw== + undici@5.28.4: version "5.28.4" resolved "https://registry.yarnpkg.com/undici/-/undici-5.28.4.tgz#6b280408edb6a1a604a9b20340f45b422e373068" @@ -21638,6 +21863,11 @@ universalify@^0.1.0: resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== +universalify@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.2.0.tgz#6451760566fa857534745ab1dde952d1b1761be0" + integrity sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg== + universalify@^2.0.0: version "2.0.1" resolved "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz" @@ -21715,6 +21945,14 @@ uri-js@^4.2.2: dependencies: punycode "^2.1.0" +url-parse@^1.5.3: + version "1.5.10" + resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.10.tgz#9d3c2f736c1d75dd3bd2be507dcc111f1e2ea9c1" + integrity sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ== + dependencies: + querystringify "^2.1.1" + requires-port "^1.0.0" + use-callback-ref@^1.3.0: version "1.3.0" resolved "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.0.tgz" @@ -22522,7 +22760,7 @@ yargs-parser@^20.2.2, yargs-parser@^20.2.3: resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz" integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== -yargs@17.7.2, yargs@^17.0.0, yargs@^17.3.1, yargs@^17.5.1, yargs@^17.6.2: +yargs@17.7.2, yargs@^17.0.0, yargs@^17.3.1, yargs@^17.5.1, yargs@^17.6.2, yargs@^17.7.2: version "17.7.2" resolved "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz" integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== @@ -22603,6 +22841,11 @@ yocto-queue@^1.0.0: resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz" integrity sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g== +yoctocolors-cjs@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/yoctocolors-cjs/-/yoctocolors-cjs-2.1.2.tgz#f4b905a840a37506813a7acaa28febe97767a242" + integrity sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA== + yoctocolors@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/yoctocolors/-/yoctocolors-2.1.1.tgz#e0167474e9fbb9e8b3ecca738deaa61dd12e56fc" From 5ab065477a34ae8033fedede34bc1ffe981ef06f Mon Sep 17 00:00:00 2001 From: Iyk Azorji Date: Wed, 11 Sep 2024 11:51:49 -0400 Subject: [PATCH 02/11] feat: add wallet error states --- .../card/error/connection-error.stories.tsx | 6 +- .../auth/card/error/connection-error.tsx | 27 ++- .../auth/card/error/icons/wallet-icon.tsx | 18 ++ .../src/components/auth/card/error/types.ts | 7 + .../react/src/icons/coinbaseWallet.tsx | 32 +++ account-kit/react/src/icons/metamask.tsx | 132 ++++++++++++ account-kit/react/src/icons/timeout.tsx | 188 ++++++++++++++++++ .../react/src/icons/walletConnectIcon.tsx | 16 ++ 8 files changed, 413 insertions(+), 13 deletions(-) create mode 100644 account-kit/react/src/components/auth/card/error/icons/wallet-icon.tsx create mode 100644 account-kit/react/src/components/auth/card/error/types.ts create mode 100644 account-kit/react/src/icons/coinbaseWallet.tsx create mode 100644 account-kit/react/src/icons/metamask.tsx create mode 100644 account-kit/react/src/icons/timeout.tsx create mode 100644 account-kit/react/src/icons/walletConnectIcon.tsx diff --git a/account-kit/react/src/components/auth/card/error/connection-error.stories.tsx b/account-kit/react/src/components/auth/card/error/connection-error.stories.tsx index b0dc57695..c73252011 100644 --- a/account-kit/react/src/components/auth/card/error/connection-error.stories.tsx +++ b/account-kit/react/src/components/auth/card/error/connection-error.stories.tsx @@ -1,12 +1,12 @@ import type { Meta, StoryObj } from "@storybook/react"; -import { ConnectionError } from "./connection-error.jsx"; +import { ConnectionError, walletTypeConfig } from "./connection-error.jsx"; const meta: Meta = { title: "Errors/ConnectionError", component: ConnectionError, args: { connectionType: "passkey", - walletType: "Coinbase Wallet", + walletType: walletTypeConfig.CoinbaseWallet.key, }, argTypes: { connectionType: { @@ -19,7 +19,7 @@ const meta: Meta = { walletType: { control: { type: "radio", - options: ["Coinbase Wallet", "MetaMask", "WalletConnect"], + options: Object.keys(walletTypeConfig), }, }, }, diff --git a/account-kit/react/src/components/auth/card/error/connection-error.tsx b/account-kit/react/src/components/auth/card/error/connection-error.tsx index 9b56e2b6c..360492305 100644 --- a/account-kit/react/src/components/auth/card/error/connection-error.tsx +++ b/account-kit/react/src/components/auth/card/error/connection-error.tsx @@ -2,13 +2,17 @@ import { useMemo } from "react"; import { ls } from "../../../../strings.js"; import { Button } from "../../../button.js"; import { PasskeyConnectionFailed } from "../../../../icons/passkeyConnectionFailed.js"; -import { EOAConnectionFailed } from "../../../../icons/EOAConnectionFailed.js"; +import { Timeout } from "../../../../icons/timeout.js"; +import type { ConnectionErrorProps, WalletType } from "./types.js"; +import { WalletIcon } from "./icons/wallet-icon.js"; -type ConnectionErrorProps = { - connectionType: "passkey" | "wallet" | "timeout"; - walletType?: "Coinbase Wallet" | "MetaMask" | "WalletConnect"; - handleTryAgain?: () => void; - handleUseAnotherMethod?: () => void; +export const walletTypeConfig: Record< + WalletType, + { name: string; key: WalletType } +> = { + CoinbaseWallet: { name: "Coinbase Wallet", key: "CoinbaseWallet" }, + MetaMask: { name: "MetaMask", key: "MetaMask" }, + WalletConnect: { name: "Wallet Connect", key: "WalletConnect" }, }; export const ConnectionError = ({ @@ -22,7 +26,10 @@ export const ConnectionError = ({ case "passkey": return ls.error.connection.passkeyTitle; case "wallet": - return ls.error.connection.walletTitle + walletType; + return ( + walletType && + ls.error.connection.walletTitle + walletTypeConfig[walletType].name + ); case "timeout": return ls.error.connection.timedOutTitle; } @@ -44,11 +51,11 @@ export const ConnectionError = ({ case "passkey": return ; case "wallet": - return ; + return walletType && ; case "timeout": - return ; + return ; } - }, [connectionType]); + }, [connectionType, walletType]); return (
diff --git a/account-kit/react/src/components/auth/card/error/icons/wallet-icon.tsx b/account-kit/react/src/components/auth/card/error/icons/wallet-icon.tsx new file mode 100644 index 000000000..e10b0ceff --- /dev/null +++ b/account-kit/react/src/components/auth/card/error/icons/wallet-icon.tsx @@ -0,0 +1,18 @@ +import { CoinbaseWallet } from "../../../../../icons/coinbaseWallet.js"; +import { EOAConnectionFailed } from "../../../../../icons/EOAConnectionFailed.js"; +import { MetaMask } from "../../../../../icons/metamask.js"; +import { WalletConnectIcon } from "../../../../../icons/walletConnectIcon.js"; +import type { WalletType } from "../types.js"; + +export const WalletIcon = ({ walletType }: { walletType: WalletType }) => { + return ( +
+ +
+ {walletType === "MetaMask" && } + {walletType === "WalletConnect" && } + {walletType === "CoinbaseWallet" && } +
+
+ ); +}; diff --git a/account-kit/react/src/components/auth/card/error/types.ts b/account-kit/react/src/components/auth/card/error/types.ts new file mode 100644 index 000000000..76a46efc3 --- /dev/null +++ b/account-kit/react/src/components/auth/card/error/types.ts @@ -0,0 +1,7 @@ +export type WalletType = "CoinbaseWallet" | "MetaMask" | "WalletConnect"; +export type ConnectionErrorProps = { + connectionType: "passkey" | "wallet" | "timeout"; + walletType?: WalletType; + handleTryAgain?: () => void; + handleUseAnotherMethod?: () => void; +}; diff --git a/account-kit/react/src/icons/coinbaseWallet.tsx b/account-kit/react/src/icons/coinbaseWallet.tsx new file mode 100644 index 000000000..4bb473fb2 --- /dev/null +++ b/account-kit/react/src/icons/coinbaseWallet.tsx @@ -0,0 +1,32 @@ +export const CoinbaseWallet = () => ( + + + + + + + + + + + +); diff --git a/account-kit/react/src/icons/metamask.tsx b/account-kit/react/src/icons/metamask.tsx new file mode 100644 index 000000000..d34a409af --- /dev/null +++ b/account-kit/react/src/icons/metamask.tsx @@ -0,0 +1,132 @@ +export const MetaMask = () => { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +}; diff --git a/account-kit/react/src/icons/timeout.tsx b/account-kit/react/src/icons/timeout.tsx new file mode 100644 index 000000000..3a7d1c0a7 --- /dev/null +++ b/account-kit/react/src/icons/timeout.tsx @@ -0,0 +1,188 @@ +export const Timeout = () => { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +}; diff --git a/account-kit/react/src/icons/walletConnectIcon.tsx b/account-kit/react/src/icons/walletConnectIcon.tsx new file mode 100644 index 000000000..27f5f3019 --- /dev/null +++ b/account-kit/react/src/icons/walletConnectIcon.tsx @@ -0,0 +1,16 @@ +export const WalletConnectIcon = () => { + return ( + + + + ); +}; From 0010d7bf413e2b495da7c3e51f2dcecc91f28551 Mon Sep 17 00:00:00 2001 From: Iyk Azorji Date: Wed, 11 Sep 2024 13:04:54 -0400 Subject: [PATCH 03/11] feat: integrate error states to wallet connect --- .../react/src/components/auth/card/eoa.tsx | 33 ++- .../auth/card/error/icons/wallet-icon.tsx | 12 +- .../react/src/icons/coinbaseWallet.tsx | 64 +++-- account-kit/react/src/icons/metamask.tsx | 264 +++++++++--------- .../react/src/icons/walletConnectIcon.tsx | 32 ++- 5 files changed, 224 insertions(+), 181 deletions(-) diff --git a/account-kit/react/src/components/auth/card/eoa.tsx b/account-kit/react/src/components/auth/card/eoa.tsx index f2bb53155..2d2733291 100644 --- a/account-kit/react/src/components/auth/card/eoa.tsx +++ b/account-kit/react/src/components/auth/card/eoa.tsx @@ -3,11 +3,13 @@ import { walletConnect } from "wagmi/connectors"; import { useChain } from "../../../hooks/useChain.js"; import { useConnect } from "../../../hooks/useConnect.js"; import { useUiConfig } from "../../../hooks/useUiConfig.js"; -import { WalletConnectIcon } from "../../../icons/walletConnect.js"; +import { WalletConnectIcon } from "../../../icons/walletConnectIcon.js"; import { Button } from "../../button.js"; import { useAuthContext, type AuthStep } from "../context.js"; import type { AuthType } from "../types.js"; import { CardContent } from "./content.js"; +import { Spinner } from "../../../icons/spinner.js"; +import { ConnectionError } from "./error/connection-error.js"; interface Props { authStep: Extract; @@ -38,16 +40,33 @@ type WalletConnectCardProps = { }; export const WalletConnectCard = ({ authStep }: WalletConnectCardProps) => { + const { setAuthStep } = useAuthContext(); + + if (authStep.error) { + return ( + setAuthStep({ type: "wallet_connect" })} + handleUseAnotherMethod={() => setAuthStep({ type: "pick_eoa" })} + /> + ); + } // If error render the error card here? return ( +
+ +
+ +
+
} description="Please follow the instructions in the popup to connect." error={authStep.error} @@ -133,7 +152,7 @@ export const EoaPickCard = () => { +
+ ); +}; diff --git a/account-kit/react/src/components/auth/card/loading/email.tsx b/account-kit/react/src/components/auth/card/loading/email.tsx index 21f0d1a17..38f995821 100644 --- a/account-kit/react/src/components/auth/card/loading/email.tsx +++ b/account-kit/react/src/components/auth/card/loading/email.tsx @@ -1,7 +1,5 @@ import { useEffect, useState } from "react"; -import { useAuthenticate } from "../../../../hooks/useAuthenticate.js"; import { useSignerStatus } from "../../../../hooks/useSignerStatus.js"; -import { Button } from "../../../button.js"; import { useAuthContext, type AuthStep } from "../../context.js"; import { Spinner } from "../../../../icons/spinner.js"; import { ls } from "../../../../strings.js"; @@ -16,13 +14,6 @@ export const LoadingEmail = ({ authStep }: LoadingEmailProps) => { // yup, re-sent and resent. I'm not fixing it const [emailResent, setEmailResent] = useState(false); - const { setAuthStep } = useAuthContext(); - const { authenticate } = useAuthenticate({ - onSuccess: () => { - setAuthStep({ type: "complete" }); - }, - }); - useEffect(() => { if (emailResent) { // set the text back to "Resend" after 2 seconds @@ -44,28 +35,6 @@ export const LoadingEmail = ({ authStep }: LoadingEmailProps) => {
{authStep.email}

- -
-
-

- {ls.loadingEmail.emailNotReceived} -

- -
-
); }; diff --git a/account-kit/react/src/components/auth/sections/Footer.tsx b/account-kit/react/src/components/auth/sections/Footer.tsx index 22df15c55..8cd16ceff 100644 --- a/account-kit/react/src/components/auth/sections/Footer.tsx +++ b/account-kit/react/src/components/auth/sections/Footer.tsx @@ -13,7 +13,7 @@ const RenderFooterText = ({ authStep }: FooterProps) => { case "initial": return ; case "email_verify": - return ; + return ; case "passkey_create": case "wallet_connect": case "passkey_verify": From cc0928570b74cb3f9430c752c1912f4821e32a88 Mon Sep 17 00:00:00 2001 From: rob chang Date: Thu, 12 Sep 2024 10:14:10 -0400 Subject: [PATCH 09/11] feat: storybook auto-docs, all auth types in story --- account-kit/react/.storybook/preview.tsx | 1 + .../src/components/auth/card/index.stories.tsx | 14 ++++++++++++++ 2 files changed, 15 insertions(+) diff --git a/account-kit/react/.storybook/preview.tsx b/account-kit/react/.storybook/preview.tsx index b874f2b01..d42be8d29 100644 --- a/account-kit/react/.storybook/preview.tsx +++ b/account-kit/react/.storybook/preview.tsx @@ -53,6 +53,7 @@ const preview: Preview = { isLight: true, }, loaders: [mswLoader], + tags: ["autodocs"], }; export default preview; diff --git a/account-kit/react/src/components/auth/card/index.stories.tsx b/account-kit/react/src/components/auth/card/index.stories.tsx index a40f93632..8870e9b2f 100644 --- a/account-kit/react/src/components/auth/card/index.stories.tsx +++ b/account-kit/react/src/components/auth/card/index.stories.tsx @@ -31,6 +31,20 @@ const Test = (props: any) => { ], ]; } + if (props.authType === "all") { + sections = [ + [{ type: "email" as const }], + [{ type: "passkey" as const }], + [ + { + type: "external_wallets", + walletConnect: { + projectId: "30e7ffaff99063e68cc9870c105d905b", + }, + }, + ], + ]; + } const ui = { theme: "dark", From 88a8abaf1f1f5200bb36452a4deb4ef712b25491 Mon Sep 17 00:00:00 2001 From: rob chang Date: Fri, 13 Sep 2024 10:15:50 -0400 Subject: [PATCH 10/11] fix: registration disclaimer opening new tab --- .../auth/card/footer/registration-disclaimer.tsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/account-kit/react/src/components/auth/card/footer/registration-disclaimer.tsx b/account-kit/react/src/components/auth/card/footer/registration-disclaimer.tsx index f5e36a6e4..019cf3277 100644 --- a/account-kit/react/src/components/auth/card/footer/registration-disclaimer.tsx +++ b/account-kit/react/src/components/auth/card/footer/registration-disclaimer.tsx @@ -3,8 +3,12 @@ import { ls } from "../../../../strings.js"; export const RegistrationDisclaimer = () => (
{ls.login.tosPrefix} - {/* eslint-disable-next-line jsx-a11y/anchor-is-valid */} - + {ls.login.tosLink}
From 9efa5454fccab246cdce10b430c15a68863bec1b Mon Sep 17 00:00:00 2001 From: rob chang Date: Fri, 13 Sep 2024 10:18:32 -0400 Subject: [PATCH 11/11] fix: remove bad token --- .../react/src/components/auth/card/error/general-error.tsx | 2 +- account-kit/react/src/tailwind/theme.ts | 1 - account-kit/react/src/tailwind/types.ts | 1 - account-kit/react/src/tailwind/utils.test.ts | 4 ---- 4 files changed, 1 insertion(+), 7 deletions(-) diff --git a/account-kit/react/src/components/auth/card/error/general-error.tsx b/account-kit/react/src/components/auth/card/error/general-error.tsx index 4a9c0bbdf..3d00673b6 100644 --- a/account-kit/react/src/components/auth/card/error/general-error.tsx +++ b/account-kit/react/src/components/auth/card/error/general-error.tsx @@ -3,7 +3,7 @@ import { ls } from "../../../../strings.js"; export const GeneralError = () => { return ( -
+

diff --git a/account-kit/react/src/tailwind/theme.ts b/account-kit/react/src/tailwind/theme.ts index d56047c58..1c57c1204 100644 --- a/account-kit/react/src/tailwind/theme.ts +++ b/account-kit/react/src/tailwind/theme.ts @@ -35,7 +35,6 @@ export function createDefaultTheme(): AccountKitTheme { "bg-surface-error": createColorSet("#DC2626", "#F87171"), "bg-surface-success": createColorSet("#16A34A", "#86EFAC"), "bg-surface-warning": createColorSet("#EA580C", "#FDBA74"), - "bg-surface-critical-light": createColorSet("#FEE2E2", "#FEE2E2"), }, borderRadius: "sm", }; diff --git a/account-kit/react/src/tailwind/types.ts b/account-kit/react/src/tailwind/types.ts index bd8673802..0f65307bf 100644 --- a/account-kit/react/src/tailwind/types.ts +++ b/account-kit/react/src/tailwind/types.ts @@ -31,7 +31,6 @@ export interface AccountKitTheme { "bg-surface-success": ColorVariantRecord; "bg-surface-warning": ColorVariantRecord; "bg-surface-error": ColorVariantRecord; - "bg-surface-critical-light": ColorVariantRecord; }; // these define the border radius base for the various components. // the mapped value applies to the smallest value used and everything scales up from there by multiple of 2 diff --git a/account-kit/react/src/tailwind/utils.test.ts b/account-kit/react/src/tailwind/utils.test.ts index 02fc66d1d..7c1976736 100644 --- a/account-kit/react/src/tailwind/utils.test.ts +++ b/account-kit/react/src/tailwind/utils.test.ts @@ -27,10 +27,6 @@ describe("tailwind utils test", () => { "dark": "#FEF2F2", "light": "#FEF2F2", }, - "bg-surface-critical-light": { - "dark": "#FEE2E2", - "light": "#FEE2E2", - }, "bg-surface-default": { "dark": "#020617", "light": "#fff",