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 f12f555b31..7f6c171c1c 100644 --- a/account-kit/react/src/components/auth/card/add-passkey.tsx +++ b/account-kit/react/src/components/auth/card/add-passkey.tsx @@ -1,4 +1,5 @@ import { useAddPasskey } from "../../../hooks/useAddPasskey.js"; +import { useUiConfig } from "../../../hooks/useUiConfig.js"; import { AddPasskeyIllustration } from "../../../icons/illustrations/add-passkey.js"; import { PasskeyShieldIllustration, @@ -8,7 +9,6 @@ import { ls } from "../../../strings.js"; import { Button } from "../../button.js"; import { PoweredBy } from "../../poweredby.js"; import { useAuthContext } from "../context.js"; -import type { AuthCardProps } from "./index.js"; const BENEFITS = [ { @@ -24,7 +24,8 @@ const BENEFITS = [ ]; // eslint-disable-next-line jsdoc/require-jsdoc -export const AddPasskey = ({ config }: { config: AuthCardProps }) => { +export const AddPasskey = () => { + const { illustrationStyle } = useUiConfig(); const { setAuthStep } = useAuthContext(); const { addPasskey, isAddingPasskey } = useAddPasskey({ onSuccess: () => { @@ -36,7 +37,7 @@ export const AddPasskey = ({ config }: { config: AuthCardProps }) => {
@@ -48,7 +49,7 @@ export const AddPasskey = ({ config }: { config: AuthCardProps }) => { {BENEFITS.map(({ title, icon: Icon, description }) => (
- +

{title}

diff --git a/account-kit/react/src/components/auth/card/index.tsx b/account-kit/react/src/components/auth/card/index.tsx index 62e62c26ea..1f8f65d0ef 100644 --- a/account-kit/react/src/components/auth/card/index.tsx +++ b/account-kit/react/src/components/auth/card/index.tsx @@ -1,54 +1,53 @@ -import { - useCallback, - useLayoutEffect, - useMemo, - useRef, - type ReactNode, -} from "react"; +import { useCallback, useLayoutEffect, useMemo, useRef } from "react"; import { useSignerStatus } from "../../../hooks/useSignerStatus.js"; import { IS_SIGNUP_QP } from "../../constants.js"; import { useAuthContext } from "../context.js"; -import type { AuthIllustrationStyle, AuthType } from "../types.js"; import { Step } from "./steps.js"; import { Notification } from "../../notification.js"; import { useAuthError } from "../../../hooks/useAuthError.js"; import { Navigation } from "../../navigation.js"; import { useAuthModal } from "../../../hooks/useAuthModal.js"; import { useElementHeight } from "../../../hooks/useElementHeight.js"; +import { useUiConfig } from "../../../hooks/useUiConfig.js"; export type AuthCardProps = { - hideError?: boolean; - header?: ReactNode; - showSignInText?: boolean; - illustrationStyle?: AuthIllustrationStyle; - // Each section can contain multiple auth types which will be grouped together - // and separated by an OR divider - sections?: AuthType[][]; className?: string; - onAuthSuccess?: () => void; }; /** * React component containing an Auth view with configured auth methods + * and options based on the config passed to the AlchemyAccountProvider * - * @param props Card Props - * @param props.header optional header for the card (good place to put your app name or logo) - * @param props.showSignInText optional boolean to show the sign in text (defaults to true) - * @param props.sections array of sections, each containing an array of auth types + * @param {AuthCardProps} props Card Props + * @param {string} props.className optional class name to apply to the card * @returns a react component containing the AuthCard */ -export const AuthCard = ( - props: AuthCardProps & { showNavigation?: boolean; showClose?: boolean } -) => { - const { showClose = false, onAuthSuccess, hideError } = props; +export const AuthCard = (props: AuthCardProps) => { + return ; +}; + +// this isn't used externally +// eslint-disable-next-line jsdoc/require-jsdoc +export const AuthCardContent = ({ + className, + showClose = false, +}: { + className?: string; + showClose?: boolean; +}) => { const { closeAuthModal } = useAuthModal(); const { status, isAuthenticating } = useSignerStatus(); const { authStep, setAuthStep } = useAuthContext(); + const error = useAuthError(); const contentRef = useRef(null); const { height } = useElementHeight(contentRef); + const { auth } = useUiConfig(); + const hideError = auth?.hideError; + const onAuthSuccess = auth?.onAuthSuccess; + // TODO: Finalize the steps that allow going back const canGoBack = useMemo(() => { return ["email_verify"].includes(authStep.type); @@ -66,6 +65,7 @@ export const AuthCard = ( useLayoutEffect(() => { if (authStep.type === "complete") { + closeAuthModal(); onAuthSuccess?.(); } else if (isAuthenticating && authStep.type === "initial") { const urlParams = new URLSearchParams(window.location.search); @@ -75,7 +75,14 @@ export const AuthCard = ( createPasskeyAfter: urlParams.get(IS_SIGNUP_QP) === "true", }); } - }, [authStep, status, isAuthenticating, setAuthStep, onAuthSuccess]); + }, [ + authStep, + status, + isAuthenticating, + setAuthStep, + onAuthSuccess, + closeAuthModal, + ]); return (
@@ -95,7 +102,9 @@ export const AuthCard = ( >
{(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 3d64e580da..570de8714c 100644 --- a/account-kit/react/src/components/auth/card/loading/email.tsx +++ b/account-kit/react/src/components/auth/card/loading/email.tsx @@ -7,17 +7,18 @@ 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"; -import type { AuthCardProps } from "../index.js"; +import { useUiConfig } from "../../../../hooks/useUiConfig.js"; interface LoadingEmailProps { - config: AuthCardProps; context: Extract; } // eslint-disable-next-line jsdoc/require-jsdoc -export const LoadingEmail = ({ config, context }: LoadingEmailProps) => { +export const LoadingEmail = ({ context }: LoadingEmailProps) => { // yup, re-sent and resent. I'm not fixing it const [emailResent, setEmailResent] = useState(false); + + const { illustrationStyle } = useUiConfig(); const { setAuthStep } = useAuthContext(); const { authenticate } = useAuthenticate({ onSuccess: () => { @@ -38,7 +39,7 @@ export const LoadingEmail = ({ config, context }: LoadingEmailProps) => {
{ +export const LoadingAuth = ({ context }: LoadingAuthProps) => { switch (context?.type) { case "email_verify": - return ; + return ; case "passkey_verify": - return ; + return ; case "email_completing": return ; default: { 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 376fd20ea0..aaad170736 100644 --- a/account-kit/react/src/components/auth/card/loading/passkey.tsx +++ b/account-kit/react/src/components/auth/card/loading/passkey.tsx @@ -2,16 +2,16 @@ import { ls } from "../../../../strings.js"; import { LoadingPasskey } from "../../../../icons/passkey.js"; import { Button } from "../../../button.js"; import { PoweredBy } from "../../../poweredby.js"; -import type { AuthCardProps } from "../index.js"; +import { useUiConfig } from "../../../../hooks/useUiConfig.js"; // eslint-disable-next-line jsdoc/require-jsdoc -export const LoadingPasskeyAuth = ({ config }: { config: AuthCardProps }) => { +export const LoadingPasskeyAuth = () => { + const { illustrationStyle } = useUiConfig(); + return (
- +

{ls.loadingPasskey.title}

diff --git a/account-kit/react/src/components/auth/card/main.tsx b/account-kit/react/src/components/auth/card/main.tsx index d1003a0164..d5fffa5603 100644 --- a/account-kit/react/src/components/auth/card/main.tsx +++ b/account-kit/react/src/components/auth/card/main.tsx @@ -2,15 +2,17 @@ import { Fragment } from "react"; import { Divider } from "../../divider.js"; import { PoweredBy } from "../../poweredby.js"; import { AuthSection } from "../sections/AuthSection.js"; -import type { AuthCardProps } from "./index.js"; import { ls } from "../../../strings.js"; +import { useUiConfig } from "../../../hooks/useUiConfig.js"; // eslint-disable-next-line jsdoc/require-jsdoc -export const MainAuthContent = ({ - header = null, - showSignInText = true, - sections, -}: AuthCardProps) => { +export const MainAuthContent = () => { + const { auth } = useUiConfig(); + + const header = auth?.header ?? null; + const sections = auth?.sections; + const showSignInText = auth?.showSignInText ?? false; + return ( <> {header} 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 f19972a167..f31eef003a 100644 --- a/account-kit/react/src/components/auth/card/passkey-added.tsx +++ b/account-kit/react/src/components/auth/card/passkey-added.tsx @@ -1,14 +1,16 @@ +import { useUiConfig } from "../../../hooks/useUiConfig.js"; import { AddedPasskeyIllustration } from "../../../icons/illustrations/added-passkey.js"; import { PoweredBy } from "../../poweredby.js"; -import type { AuthCardProps } from "./index.js"; // eslint-disable-next-line jsdoc/require-jsdoc -export function PasskeyAdded({ config }: { config: AuthCardProps }) { +export function PasskeyAdded() { + const { illustrationStyle } = useUiConfig(); + return (
diff --git a/account-kit/react/src/components/auth/card/steps.tsx b/account-kit/react/src/components/auth/card/steps.tsx index a60a31caf5..ac0562ec56 100644 --- a/account-kit/react/src/components/auth/card/steps.tsx +++ b/account-kit/react/src/components/auth/card/steps.tsx @@ -1,29 +1,28 @@ import { useAuthContext } from "../context.js"; import { AddPasskey } from "./add-passkey.js"; import { EoaConnectCard } from "./eoa.js"; -import type { AuthCardProps } from "./index.js"; import { LoadingAuth } from "./loading/index.js"; import { MainAuthContent } from "./main.js"; import { PasskeyAdded } from "./passkey-added.js"; // eslint-disable-next-line jsdoc/require-jsdoc -export const Step = (props: AuthCardProps) => { +export const Step = () => { const { authStep } = useAuthContext(); switch (authStep.type) { case "email_verify": case "passkey_verify": case "email_completing": - return ; + return ; case "passkey_create": - return ; + return ; case "passkey_create_success": - return ; + return ; case "eoa_connect": return ; case "complete": case "initial": default: - return ; + return ; } }; diff --git a/account-kit/react/src/components/auth/modal.tsx b/account-kit/react/src/components/auth/modal.tsx index 4e4556a77e..403918e3ea 100644 --- a/account-kit/react/src/components/auth/modal.tsx +++ b/account-kit/react/src/components/auth/modal.tsx @@ -1,28 +1,16 @@ -import { AuthCard } from "./card/index.js"; -import { type AlchemyAccountsUIConfig } from "../../context.js"; +import { AuthCardContent } from "./card/index.js"; import { useAuthModal } from "../../hooks/useAuthModal.js"; import { Dialog } from "../dialog/dialog.js"; +import { useUiConfig } from "../../hooks/useUiConfig.js"; -type AuthModalProps = { - open: boolean; - hideError?: boolean; - auth: NonNullable; -}; - -export const AuthModal = ({ open, hideError, auth }: AuthModalProps) => { - const { closeAuthModal } = useAuthModal(); +export const AuthModal = () => { + const { modalBaseClassName } = useUiConfig(); + const { isOpen, closeAuthModal } = useAuthModal(); return ( - -
- closeAuthModal()} - showClose - /> + +
+
); diff --git a/account-kit/react/src/components/auth/types.ts b/account-kit/react/src/components/auth/types.ts index 344a96d8a9..a6bf6199bf 100644 --- a/account-kit/react/src/components/auth/types.ts +++ b/account-kit/react/src/components/auth/types.ts @@ -8,5 +8,3 @@ export type AuthType = } | { type: "passkey" } | { type: "injected" }; - -export type AuthIllustrationStyle = "outline" | "linear" | "filled" | "flat"; diff --git a/account-kit/react/src/components/navigation.tsx b/account-kit/react/src/components/navigation.tsx index 1fda6ac1b1..3551686ba4 100644 --- a/account-kit/react/src/components/navigation.tsx +++ b/account-kit/react/src/components/navigation.tsx @@ -4,13 +4,13 @@ import { Button } from "./button.js"; interface NavigationProps { onBack?: () => void; onClose: () => void; - showBack: boolean; + showBack?: boolean; showClose: boolean; } // eslint-disable-next-line jsdoc/require-jsdoc export const Navigation = ({ - showBack, + showBack = false, showClose, onBack, onClose, diff --git a/account-kit/react/src/context.tsx b/account-kit/react/src/context.tsx index 15dc788371..6fa87cbf83 100644 --- a/account-kit/react/src/context.tsx +++ b/account-kit/react/src/context.tsx @@ -14,21 +14,24 @@ import { useMemo, useState, } from "react"; -import type { AuthCardProps } from "./components/auth/card/index.js"; import { AuthModalContext, type AuthStep } from "./components/auth/context.js"; import { AuthModal } from "./components/auth/modal.js"; import { IS_SIGNUP_QP } from "./components/constants.js"; import { NoAlchemyAccountContextError } from "./errors.js"; import { useSignerStatus } from "./hooks/useSignerStatus.js"; import { Hydrate } from "./hydrate.js"; +import type { AlchemyAccountsConfigWithUI } from "./createConfig.js"; +import type { AlchemyAccountsUIConfig } from "./types.js"; export type AlchemyAccountContextProps = | { config: AlchemyAccountsConfig; queryClient: QueryClient; ui?: { + config: AlchemyAccountsUIConfig; openAuthModal: () => void; closeAuthModal: () => void; + isModalOpen: boolean; }; } | undefined; @@ -37,24 +40,10 @@ export const AlchemyAccountContext = createContext< AlchemyAccountContextProps | undefined >(undefined); -export type AlchemyAccountsUIConfig = { - auth?: AuthCardProps & { addPasskeyOnSignup?: boolean }; - /** - * If hideError is true, then the auth component will not - * render the global error component - */ - hideError?: boolean; -}; - export type AlchemyAccountsProviderProps = { - config: AlchemyAccountsConfig; + config: AlchemyAccountsConfigWithUI; initialState?: AlchemyClientState; queryClient: QueryClient; - /** - * If auth config is provided, then the auth modal will be added - * to the DOM and can be controlled via the `useAuthModal` hook - */ - uiConfig?: AlchemyAccountsUIConfig; }; /** @@ -91,7 +80,7 @@ export const useAlchemyAccountContext = ( export const AlchemyAccountProvider = ( props: React.PropsWithChildren ) => { - const { config, queryClient, children, uiConfig } = props; + const { config, queryClient, children } = props; const [isModalOpen, setIsModalOpen] = useState(false); @@ -102,14 +91,16 @@ export const AlchemyAccountProvider = ( () => ({ config, queryClient, - ui: uiConfig + ui: config.ui ? { + config: config.ui, openAuthModal, closeAuthModal, + isModalOpen, } : undefined, }), - [config, queryClient, uiConfig, openAuthModal, closeAuthModal] + [config, queryClient, openAuthModal, closeAuthModal, isModalOpen] ); const { status, isAuthenticating } = useSignerStatus(initialContext); @@ -120,14 +111,14 @@ export const AlchemyAccountProvider = ( useEffect(() => { if ( status === "AWAITING_EMAIL_AUTH" && - uiConfig?.auth?.addPasskeyOnSignup + config.ui?.auth?.addPasskeyOnSignup ) { const urlParams = new URLSearchParams(window.location.search); if (urlParams.get(IS_SIGNUP_QP) !== "true") return; openAuthModal(); } - }, [status, uiConfig?.auth, openAuthModal]); + }, [status, config.ui, openAuthModal]); return ( @@ -140,13 +131,7 @@ export const AlchemyAccountProvider = ( }} > {children} - {uiConfig?.auth && ( - - )} + diff --git a/account-kit/react/src/createConfig.ts b/account-kit/react/src/createConfig.ts new file mode 100644 index 0000000000..0c8e4003d2 --- /dev/null +++ b/account-kit/react/src/createConfig.ts @@ -0,0 +1,31 @@ +import { + createConfig as createCoreConfig, + type AlchemyAccountsConfig, + type CreateConfigProps, +} from "@account-kit/core"; +import type { AlchemyAccountsUIConfig } from "./types"; + +export type AlchemyAccountsConfigWithUI = AlchemyAccountsConfig & { + ui?: AlchemyAccountsUIConfig; +}; + +/** + * Wraps the `createConfig` that is exported from `@aa-sdk/core` to allow passing + * an additional argument, the configuration object for the Auth Components UI + * (the modal and AuthCard). + * + * @param {CreateConfigProps} props for creating an alchemy account config + * @param {AlchemyAccountsUIConfig} ui the configuration to use for the Auth Components UI + * @returns an alchemy account config object containing the core and client store, as well as the UI config + */ +export const createConfig = ( + props: CreateConfigProps, + ui: AlchemyAccountsUIConfig +): AlchemyAccountsConfigWithUI => { + const config = createCoreConfig(props); + + return { + ...config, + ui, + }; +}; diff --git a/account-kit/react/src/hooks/useAuthModal.ts b/account-kit/react/src/hooks/useAuthModal.ts index 20e8d53541..75e1ddb43a 100644 --- a/account-kit/react/src/hooks/useAuthModal.ts +++ b/account-kit/react/src/hooks/useAuthModal.ts @@ -14,6 +14,7 @@ export const useAuthModal = () => { } return { + isOpen: ui.isModalOpen, openAuthModal: ui.openAuthModal, closeAuthModal: ui.closeAuthModal, }; diff --git a/account-kit/react/src/hooks/useUiConfig.ts b/account-kit/react/src/hooks/useUiConfig.ts new file mode 100644 index 0000000000..172448ad69 --- /dev/null +++ b/account-kit/react/src/hooks/useUiConfig.ts @@ -0,0 +1,13 @@ +import { useAlchemyAccountContext } from "../context.js"; +import { MissingUiConfigError } from "../errors.js"; + +export const useUiConfig = () => { + const { ui } = useAlchemyAccountContext(); + if (ui == null) { + throw new MissingUiConfigError("useUiConfig"); + } + + return { + ...ui.config, + }; +}; diff --git a/account-kit/react/src/icons/illustrations/types.ts b/account-kit/react/src/icons/illustrations/types.ts index 5d94f52449..153b690764 100644 --- a/account-kit/react/src/icons/illustrations/types.ts +++ b/account-kit/react/src/icons/illustrations/types.ts @@ -1,5 +1,5 @@ import type { SVGProps } from "react"; -import type { AuthIllustrationStyle } from "../../components/auth/types"; +import type { AuthIllustrationStyle } from "../../types.js"; export type IllustrationProps = JSX.IntrinsicAttributes & SVGProps & { diff --git a/account-kit/react/src/index.ts b/account-kit/react/src/index.ts index f922cf67b9..69e4d4f4ea 100644 --- a/account-kit/react/src/index.ts +++ b/account-kit/react/src/index.ts @@ -1,8 +1,5 @@ -export { - cookieStorage, - createConfig, - type CreateConfigProps, -} from "@account-kit/core"; +export { cookieStorage, type CreateConfigProps } from "@account-kit/core"; +export { createConfig } from "./createConfig.js"; export type * from "./context.js"; export { AlchemyAccountContext, @@ -10,6 +7,7 @@ export { useAlchemyAccountContext, } from "./context.js"; export { NoAlchemyAccountContextError } from "./errors.js"; +export { type AlchemyAccountsUIConfig } from "./types.js"; export type * from "./hooks/useAccount.js"; export { useAccount } from "./hooks/useAccount.js"; export type * from "./hooks/useAddPasskey.js"; diff --git a/account-kit/react/src/types.ts b/account-kit/react/src/types.ts index 883ee1d8e0..cec6028653 100644 --- a/account-kit/react/src/types.ts +++ b/account-kit/react/src/types.ts @@ -1,4 +1,41 @@ import type { UseMutationOptions } from "@tanstack/react-query"; +import type { ReactNode } from "react"; +import type { AuthType } from "./components/auth/types.js"; + +export type AlchemyAccountsUIConfig = { + auth?: { + /** + * If this is true, then auth components will prompt users to add + * a passkey after signing in for the first time + */ + addPasskeyOnSignup?: boolean; + header?: ReactNode; + /** + * If hideError is true, then the auth component will not + * render the global error component + */ + hideError?: boolean; + onAuthSuccess?: () => void; + /** + * Each section can contain multiple auth types which will be grouped together + * and separated by an OR divider + */ + sections: AuthType[][]; + /** + * Whether to show the "Sign in" header text in the first auth step + */ + showSignInText?: boolean; + }; + illustrationStyle?: "outline" | "linear" | "filled" | "flat"; + /** + * This class name will be applied to any modals that are rendered + */ + modalBaseClassName?: string; +}; + +export type AuthIllustrationStyle = NonNullable< + AlchemyAccountsUIConfig["illustrationStyle"] +>; /** * Base hook mutation arguments. diff --git a/examples/ui-demo/src/app/page.tsx b/examples/ui-demo/src/app/page.tsx index d0b3b61246..f40cf74040 100644 --- a/examples/ui-demo/src/app/page.tsx +++ b/examples/ui-demo/src/app/page.tsx @@ -30,7 +30,7 @@ export default function Home() { className={`flex flex-col flex-1 px-10 py-6 w-full max-w-screen-2xl mx-auto overflow-hidden ${inter.className}`} >
-
+
diff --git a/examples/ui-demo/src/app/providers.tsx b/examples/ui-demo/src/app/providers.tsx index 95cf2495bf..08608f0406 100644 --- a/examples/ui-demo/src/app/providers.tsx +++ b/examples/ui-demo/src/app/providers.tsx @@ -1,37 +1,43 @@ "use client"; -import { sepolia } from "@aa-sdk/core"; -import { createConfig } from "@account-kit/core"; -import { getBorderRadiusBaseVariableName, getColorVariableName } from "@account-kit/react/tailwind" -import { AlchemyAccountProvider, AlchemyAccountsProviderProps } from "@account-kit/react"; +import { sepolia } from "@account-kit/infra" +import { getBorderRadiusBaseVariableName, getBorderRadiusValue, getColorVariableName } from "@account-kit/react/tailwind" +import { AlchemyAccountProvider, AlchemyAccountsProviderProps, AlchemyAccountsUIConfig, AuthType, createConfig } from "@account-kit/react"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { PropsWithChildren, Suspense, useEffect, useMemo, useState } from "react"; import { Config, ConfigContext, DEFAULT_CONFIG } from "./state"; -import { getBorderRadiusValue } from "@account-kit/react/tailwind"; - -const alchemyConfig = createConfig({ - // required - rpcUrl: "/api/rpc", - chain: sepolia, - ssr: true, -}); const queryClient = new QueryClient(); export const Providers = (props: PropsWithChildren<{}>) => { const [config, setConfig] = useState(DEFAULT_CONFIG); - const uiConfig: AlchemyAccountsProviderProps["uiConfig"] = useMemo(() => { - return { - // TODO: read sections fron `config` too + // Sync Alchemy auth UI config + const alchemyConfig: AlchemyAccountsProviderProps["config"] = useMemo(() => { + const sections: AuthType[][] = [[{ type: "passkey" as const }]] + if (config.auth.showEmail) { + sections.unshift([{ type: "email" as const }]) + } + + const uiConfig: AlchemyAccountsUIConfig = { + illustrationStyle: config.ui.illustrationStyle, auth: { - sections: [[{ type: "email" }], [{ type: "passkey" }]], + sections, addPasskeyOnSignup: config.auth.addPasskey, - illustrationStyle: config.ui.illustrationStyle, + showSignInText: true, + header: , }, }; + + return createConfig({ + // required + rpcUrl: "/api/rpc", + chain: sepolia, + ssr: true, + }, uiConfig); }, [config]); + // Sync CSS variables useEffect(() => { const root = document.querySelector(':root') as HTMLElement; @@ -56,7 +62,6 @@ export const Providers = (props: PropsWithChildren<{}>) => { {props.children} @@ -66,3 +71,17 @@ export const Providers = (props: PropsWithChildren<{}>) => { ); }; + +function AuthCardHeader({ logoDark, logoLight, theme }: Pick) { + const logo = theme === "dark" ? logoDark : logoLight; + + if (!logo) return null; + + return ( + {logo.fileName} + ); +}; diff --git a/examples/ui-demo/src/components/configuration/PhotoUpload.tsx b/examples/ui-demo/src/components/configuration/PhotoUpload.tsx index b2f2a238ac..ad9fcae332 100644 --- a/examples/ui-demo/src/components/configuration/PhotoUpload.tsx +++ b/examples/ui-demo/src/components/configuration/PhotoUpload.tsx @@ -45,7 +45,7 @@ export function PhotoUploads({ mode }: { mode: "dark" | "light" }) { } return ( -
+
{logo?.fileSrc ? null : ( @@ -63,7 +64,7 @@ export function PhotoUploads({ mode }: { mode: "dark" | "light" }) {
{mode === "light" ? "Light" : "Dark"} mode
-
+
{logo?.fileName ? truncatedFileName(logo.fileName) : "File name"}
{logo ? ( diff --git a/examples/ui-demo/src/components/preview/AuthCardWrapper.tsx b/examples/ui-demo/src/components/preview/AuthCardWrapper.tsx index 8ff18aef57..b1ba04a53c 100644 --- a/examples/ui-demo/src/components/preview/AuthCardWrapper.tsx +++ b/examples/ui-demo/src/components/preview/AuthCardWrapper.tsx @@ -1,7 +1,6 @@ import { useConfig } from "@/app/state"; import { cn } from "@/lib/utils"; -import { AuthCard, AuthType, useLogout, useUser } from "@account-kit/react"; -import { useMemo } from "react"; +import { AuthCard, useLogout, useUser } from "@account-kit/react"; export function AuthCardWrapper({ className }: { className?: string }) { const user = useUser(); @@ -9,17 +8,6 @@ export function AuthCardWrapper({ className }: { className?: string }) { const { config } = useConfig(); const { logout } = useLogout(); - const sections = useMemo(() => { - const output = []; - if (config.auth.showEmail) { - output.push([{ type: "email" as const }]); - } - - output.push([{ type: "passkey" as const }]); - - return output; - }, [config.auth]); - return (
- } - showSignInText - showNavigation - illustrationStyle={config.ui.illustrationStyle} - sections={sections} - /> +
) : ( @@ -46,23 +28,3 @@ export function AuthCardWrapper({ className }: { className?: string }) {
); } - -function AuthCardHeader() { - const { - config: { - ui: { logoDark, logoLight, theme }, - }, - } = useConfig(); - - const logo = theme === "dark" ? logoDark : logoLight; - - if (!logo) return null; - - return ( - {logo.fileName} - ); -} diff --git a/examples/ui-demo/src/components/preview/CodePreview.tsx b/examples/ui-demo/src/components/preview/CodePreview.tsx index a6f1ba2d9d..9e847445eb 100644 --- a/examples/ui-demo/src/components/preview/CodePreview.tsx +++ b/examples/ui-demo/src/components/preview/CodePreview.tsx @@ -24,14 +24,14 @@ export function CodePreview({ className }: { className?: string }) {
-
-
Style
- -
Config
+
+
Style
+ +
); } @@ -93,18 +93,19 @@ function getConfigCode(config: Config) { sections.push([{ type: "passkey" }]) return dedent` - const config = createConfig({ - // required - rpcUrl: "/api/rpc", - chain: sepolia, - ssr: true, - }); - const uiConfig = { + illustrationStyle: ${config.ui.illustrationStyle}, auth: { sections: ${JSON.stringify(sections)}, addPasskeyOnSignup: ${config.auth.addPasskey}, }, }; + + const config = createConfig({ + // required + rpcUrl: "/api/rpc", + chain: sepolia, + ssr: true, + }, uiConfig); ` } diff --git a/examples/ui-demo/src/components/shared/Button.tsx b/examples/ui-demo/src/components/shared/Button.tsx index b71628b3c4..0e367906a1 100644 --- a/examples/ui-demo/src/components/shared/Button.tsx +++ b/examples/ui-demo/src/components/shared/Button.tsx @@ -3,10 +3,12 @@ import { PropsWithChildren } from "react"; export function Button({ children, className, -}: PropsWithChildren<{ className: string }>) { + ...rest +}: PropsWithChildren & { className?: string; }>) { return (