diff --git a/examples/ui-demo/src/app/config.tsx b/examples/ui-demo/src/app/config.tsx
index d827762cf8..176447f23e 100644
--- a/examples/ui-demo/src/app/config.tsx
+++ b/examples/ui-demo/src/app/config.tsx
@@ -36,9 +36,15 @@ export type Config = {
}
| undefined;
};
+ walletType: WalletTypes;
supportUrl?: string;
};
+export enum WalletTypes {
+ smart = "smart",
+ hybrid7702 = "7702",
+}
+
export const DEFAULT_CONFIG: Config = {
auth: {
showEmail: true,
@@ -65,6 +71,7 @@ export const DEFAULT_CONFIG: Config = {
logoLight: undefined,
logoDark: undefined,
},
+ walletType: WalletTypes.smart,
};
export const queryClient = new QueryClient();
diff --git a/examples/ui-demo/src/app/page.tsx b/examples/ui-demo/src/app/page.tsx
index 06ef43b115..d88304c44a 100644
--- a/examples/ui-demo/src/app/page.tsx
+++ b/examples/ui-demo/src/app/page.tsx
@@ -21,6 +21,10 @@ import { AuthCardWrapper } from "../components/preview/AuthCardWrapper";
import { CodePreview } from "../components/preview/CodePreview";
import { CodePreviewSwitch } from "../components/shared/CodePreviewSwitch";
import { TopNav } from "../components/topnav/TopNav";
+import { Configuration } from "@/components/configuration/Configuration";
+import { Wrapper7702 } from "@/components/shared/7702/Wrapper";
+import { useConfigStore } from "@/state";
+import { WalletTypes } from "./config";
const publicSans = Public_Sans({
subsets: ["latin"],
@@ -37,6 +41,7 @@ export default function Home() {
const user = useUser();
const theme = useTheme();
const isEOAUser = user?.type === "eoa";
+ const { walletType } = useConfigStore();
return (
@@ -129,22 +135,45 @@ export default function Home() {
- {!user &&
}
- {isEOAUser && (
-
- )}
- {user && !isEOAUser &&
}
+
{user && !isEOAUser &&
}
);
}
+
+const RenderContent = ({
+ user,
+ isEOAUser,
+ isSmartWallet,
+}: {
+ user: boolean;
+ isEOAUser: boolean;
+ isSmartWallet: boolean;
+}) => {
+ if (!user) {
+ return ;
+ }
+ if (isEOAUser) {
+ return (
+
+ );
+ }
+ if (isSmartWallet) {
+ return ;
+ }
+ return ;
+};
diff --git a/examples/ui-demo/src/components/configuration/Configuration.tsx b/examples/ui-demo/src/components/configuration/Configuration.tsx
new file mode 100644
index 0000000000..1b471a08e4
--- /dev/null
+++ b/examples/ui-demo/src/components/configuration/Configuration.tsx
@@ -0,0 +1,53 @@
+// import { useState } from "react";
+import { cn } from "@/lib/utils";
+
+import { SettingsIcon } from "../icons/settings";
+// import { HelpTooltip } from "../shared/HelpTooltip";
+import { WalletTypeSwitch } from "../shared/WalletTypeSwitch";
+import ExternalLink from "../shared/ExternalLink";
+import { useConfigStore } from "@/state";
+import { WalletTypes } from "@/app/config";
+
+export const Configuration = ({ className }: { className?: string }) => {
+ const { setWalletType, walletType } = useConfigStore();
+ // const [walletType, setWalletType] = useState(WalletTypes.smart);
+
+ const onSwitchWalletType = () => {
+ setWalletType(
+ walletType === WalletTypes.smart
+ ? WalletTypes.hybrid7702
+ : WalletTypes.smart
+ );
+ };
+
+ return (
+
+
+
+ Configuration
+
+
+
+ Embedded Wallet Type
+
+ {/* */}
+
+
+
+ Sentence describing all of the value props fo 7702 and educating the
+ user. Curious about what this means?
+
+ Learn more.
+
+
+
+
+ );
+};
diff --git a/examples/ui-demo/src/components/icons/key.tsx b/examples/ui-demo/src/components/icons/key.tsx
new file mode 100644
index 0000000000..366380ad26
--- /dev/null
+++ b/examples/ui-demo/src/components/icons/key.tsx
@@ -0,0 +1,24 @@
+export const Key = ({ className }: { className?: string }) => (
+
+);
diff --git a/examples/ui-demo/src/components/icons/loading.tsx b/examples/ui-demo/src/components/icons/loading.tsx
index ef89746f77..eb5041e0d8 100644
--- a/examples/ui-demo/src/components/icons/loading.tsx
+++ b/examples/ui-demo/src/components/icons/loading.tsx
@@ -1,5 +1,5 @@
import { useTheme } from "@/state/useTheme";
-export const LoadingIcon = () => {
+export const LoadingIcon = ({ className }: { className?: string }) => {
const theme = useTheme();
const animationClass =
theme === "dark" ? "animate-ui-loading-dark" : "animate-ui-loading-light";
@@ -11,6 +11,7 @@ export const LoadingIcon = () => {
viewBox="0 0 48 48"
fill="none"
xmlns="http://www.w3.org/2000/svg"
+ className={className}
>
) => (
+
+);
diff --git a/examples/ui-demo/src/components/preview/AuthCardWrapper.tsx b/examples/ui-demo/src/components/preview/AuthCardWrapper.tsx
index fb62be1ccf..1914a369f8 100644
--- a/examples/ui-demo/src/components/preview/AuthCardWrapper.tsx
+++ b/examples/ui-demo/src/components/preview/AuthCardWrapper.tsx
@@ -4,6 +4,9 @@ import { cn } from "@/lib/utils";
import { useTheme } from "@/state/useTheme";
import { AuthCard, useUser } from "@account-kit/react";
import { EOAPostLogin } from "../shared/eoa-post-login/EOAPostLogin";
+import { Wrapper7702 } from "../shared/7702/Wrapper";
+import { useConfigStore } from "@/state";
+import { WalletTypes } from "@/app/config";
import { MintCard } from "../shared/mint-card/MintCard";
import { Debug7702Button } from "../shared/7702/Debug7702Button";
@@ -26,6 +29,7 @@ export function AuthCardWrapper({ className }: { className?: string }) {
}
const RenderContent = () => {
+ const { walletType } = useConfigStore();
const user = useUser();
const hasUser = !!user;
@@ -55,10 +59,5 @@ const RenderContent = () => {
);
}
- return (
-
-
-
-
- );
+ return walletType === WalletTypes.smart ? : ;
};
diff --git a/examples/ui-demo/src/components/shared/7702/Button.tsx b/examples/ui-demo/src/components/shared/7702/Button.tsx
new file mode 100644
index 0000000000..6d19275a90
--- /dev/null
+++ b/examples/ui-demo/src/components/shared/7702/Button.tsx
@@ -0,0 +1,18 @@
+import { PropsWithChildren } from "react";
+
+export const Button = ({
+ children,
+ className,
+ ...rest
+}: PropsWithChildren<
+ React.ComponentProps<"button"> & { className?: string }
+>) => {
+ return (
+
+ );
+};
diff --git a/examples/ui-demo/src/components/shared/7702/MintCard7702.tsx b/examples/ui-demo/src/components/shared/7702/MintCard7702.tsx
new file mode 100644
index 0000000000..1094b117b4
--- /dev/null
+++ b/examples/ui-demo/src/components/shared/7702/MintCard7702.tsx
@@ -0,0 +1,94 @@
+import Image from "next/image";
+import { LoadingIcon } from "@/components/icons/loading";
+import { Button } from "./Button";
+import { MintStages } from "./MintStages";
+
+type NFTLoadingState = "initial" | "loading" | "success";
+export type MintStatus = {
+ signing: NFTLoadingState;
+ gas: NFTLoadingState;
+ batch: NFTLoadingState;
+};
+
+export const MintCard7702 = ({
+ isLoading,
+ isDisabled,
+ status,
+ nftTransfered,
+ handleCollectNFT,
+ uri,
+}: {
+ isLoading: boolean;
+ isDisabled?: boolean;
+ status: MintStatus;
+ nftTransfered: boolean;
+ handleCollectNFT: () => void;
+ uri?: string;
+}) => {
+ return (
+
+ {uri ? (
+
+
+
+ ) : (
+
+
+
+ )}
+
+
+ Gasless transactions
+
+
+ {!nftTransfered ? (
+ <>
+
+ Sponsor gas and sign in the background for a one-click transaction
+ experience.
+
+
+
Gas Fee
+
+
+ $0.02
+
+
+ Free
+
+
+
+ >
+ ) : (
+
+ )}
+
+
+ );
+};
diff --git a/examples/ui-demo/src/components/shared/7702/MintStages.tsx b/examples/ui-demo/src/components/shared/7702/MintStages.tsx
new file mode 100644
index 0000000000..70708d7ec0
--- /dev/null
+++ b/examples/ui-demo/src/components/shared/7702/MintStages.tsx
@@ -0,0 +1,52 @@
+import { CheckCircleFilledIcon } from "@/components/icons/check-circle-filled";
+import { LoadingIcon } from "@/components/icons/loading";
+import { MintStatus } from "./MintCard7702";
+import { loadingState } from "./Transactions";
+
+export const MintStages = ({ status }: { status: MintStatus }) => {
+ return (
+
+
+
+
+
+ );
+};
+
+const Stage = ({
+ icon,
+ description,
+ className,
+}: {
+ icon: loadingState;
+ description: string | JSX.Element;
+ className?: string;
+}) => {
+ return (
+
+
{getMintIcon(icon)}
+
{description}
+
+ );
+};
+
+export const getMintIcon = (icon: loadingState) => {
+ switch (icon) {
+ case "loading":
+ case "initial":
+ return ;
+ case "success":
+ return (
+
+ );
+ }
+};
diff --git a/examples/ui-demo/src/components/shared/7702/Transactions.tsx b/examples/ui-demo/src/components/shared/7702/Transactions.tsx
new file mode 100644
index 0000000000..c4ea547ea3
--- /dev/null
+++ b/examples/ui-demo/src/components/shared/7702/Transactions.tsx
@@ -0,0 +1,62 @@
+import { ExternalLinkIcon } from "@/components/icons/external-link";
+import { TransactionType } from "./useTransaction";
+import { CheckCircleFilledIcon } from "@/components/icons/check-circle-filled";
+import { LoadingIcon } from "@/components/icons/loading";
+
+export type loadingState = "loading" | "success" | "initial";
+
+export const Transactions = ({
+ transactions,
+}: {
+ transactions: TransactionType[];
+}) => {
+ return (
+
+ {transactions.map((transaction, i) => (
+
+ ))}
+
+ );
+};
+
+const Transaction = ({
+ className,
+ externalLink,
+ description,
+ state,
+}: TransactionType & { className?: string }) => {
+ const getText = () => {
+ if (state === "initial") {
+ return "...";
+ }
+ if (state === "initiating") {
+ return "Initiating buy...";
+ }
+ if (state === "next") {
+ return "Next buy in 10 seconds...";
+ }
+ return description;
+ };
+
+ return (
+
+
+
+ {state === "complete" ? (
+
+ ) : (
+
+ )}
+
+
{getText()}
+
+ {externalLink && state === "complete" && (
+
+
+
+
+
+ )}
+
+ );
+};
diff --git a/examples/ui-demo/src/components/shared/7702/TransactionsCard.tsx b/examples/ui-demo/src/components/shared/7702/TransactionsCard.tsx
new file mode 100644
index 0000000000..1828f741e5
--- /dev/null
+++ b/examples/ui-demo/src/components/shared/7702/TransactionsCard.tsx
@@ -0,0 +1,61 @@
+import { Key } from "@/components/icons/key";
+import { Button } from "./Button";
+import { useState } from "react";
+import { Transactions } from "./Transactions";
+import { TransactionType } from "./useTransaction";
+
+export const TransactionsCard = ({
+ isLoading,
+ isDisabled,
+ transactions,
+ handleTransactions,
+}: {
+ isLoading: boolean;
+ isDisabled?: boolean;
+ transactions: TransactionType[];
+ handleTransactions: () => void;
+}) => {
+ const [hasClicked, setHasClicked] = useState(false);
+ const handleClick = () => {
+ setHasClicked(true);
+ handleTransactions();
+ };
+ return (
+
+
+
+ Recurring transactions
+
+ {!hasClicked ? (
+
+ Set up a dollar-cost average order by creating a session key with
+ permission to buy ETH every 10 seconds.
+
+ ) : (
+
+ )}
+
+
+
+ );
+};
diff --git a/examples/ui-demo/src/components/shared/7702/Wrapper.tsx b/examples/ui-demo/src/components/shared/7702/Wrapper.tsx
new file mode 100644
index 0000000000..6cfe87382a
--- /dev/null
+++ b/examples/ui-demo/src/components/shared/7702/Wrapper.tsx
@@ -0,0 +1,40 @@
+import { RenderUserConnectionAvatar } from "../user-connection-avatar/RenderUserConnectionAvatar";
+import { MintCard7702 } from "./MintCard7702";
+import { TransactionsCard } from "./TransactionsCard";
+import { useMint } from "./useMint";
+import { useTransactions } from "./useTransaction";
+
+export const Wrapper7702 = () => {
+ const {
+ isLoading: isLoadingTransactions,
+ transactions,
+ handleTransactions,
+ } = useTransactions();
+ const {
+ isLoading: isLoadingMint,
+ status,
+ nftTransfered,
+ handleCollectNFT,
+ uri,
+ } = useMint();
+ return (
+
+ );
+};
diff --git a/examples/ui-demo/src/components/shared/7702/useMint.tsx b/examples/ui-demo/src/components/shared/7702/useMint.tsx
new file mode 100644
index 0000000000..be0c0072ef
--- /dev/null
+++ b/examples/ui-demo/src/components/shared/7702/useMint.tsx
@@ -0,0 +1,117 @@
+import {
+ useSendUserOperation,
+ useSmartAccountClient,
+} from "@account-kit/react";
+import { useQuery } from "@tanstack/react-query";
+import { AccountKitNftMinterABI, nftContractAddress } from "@/utils/config";
+import { useCallback, useState } from "react";
+import { useToast } from "@/hooks/useToast";
+import { encodeFunctionData } from "viem";
+import { MintStatus } from "./MintCard7702";
+
+const initialValuePropState = {
+ signing: "initial",
+ gas: "initial",
+ batch: "initial",
+} satisfies MintStatus;
+
+export const useMint = () => {
+ const [status, setStatus] = useState(initialValuePropState);
+ const [nftTransfered, setNftTransfered] = useState(false);
+ const isLoading = Object.values(status).some((x) => x === "loading");
+ const { setToast } = useToast();
+ const { client } = useSmartAccountClient({ type: "LightAccount" });
+ const handleSuccess = () => {
+ setStatus(() => ({
+ batch: "success",
+ gas: "success",
+ signing: "success",
+ }));
+ // Current design does not have a success toast, leaving commented to implement later.
+ // setToast({
+ // type: "success",
+ // text: (
+ // <>
+ //
+ // {`You've collected your NFT!`}
+ //
+ //
+ // {`You've successfully collected your NFT! Refresh to mint
+ // again.`}
+ //
+ // >
+ // ),
+ // open: true,
+ // });
+ };
+
+ const handleError = (error: Error) => {
+ console.error(error);
+ setStatus(initialValuePropState);
+ setNftTransfered(false);
+ setToast({
+ type: "error",
+ text: "There was a problem with that action",
+ open: true,
+ });
+ };
+
+ const { data: uri } = useQuery({
+ queryKey: ["contractURI", nftContractAddress],
+ queryFn: async () => {
+ const uri = await client?.readContract({
+ address: nftContractAddress,
+ abi: AccountKitNftMinterABI,
+ functionName: "baseURI",
+ });
+ return uri;
+ },
+ enabled: !!client && !!client?.readContract,
+ });
+ const { sendUserOperation } = useSendUserOperation({
+ client,
+ waitForTxn: true,
+ onError: handleError,
+ onSuccess: handleSuccess,
+ onMutate: () => {
+ setTimeout(() => {
+ setStatus((prev) => ({ ...prev, signing: "success" }));
+ }, 500);
+ setTimeout(() => {
+ setStatus((prev) => ({ ...prev, gas: "success" }));
+ }, 750);
+ },
+ });
+
+ const handleCollectNFT = useCallback(async () => {
+ if (!client) {
+ console.error("no client");
+ return;
+ }
+ setNftTransfered(true);
+
+ setStatus({
+ signing: "loading",
+ gas: "loading",
+ batch: "loading",
+ });
+ sendUserOperation({
+ uo: {
+ target: nftContractAddress,
+ data: encodeFunctionData({
+ abi: AccountKitNftMinterABI,
+ functionName: "mintTo",
+ args: [client.getAddress()],
+ }),
+ },
+ });
+ }, [client, sendUserOperation]);
+
+ return {
+ isLoading,
+ status,
+ nftTransfered,
+ handleCollectNFT,
+ uri,
+ };
+};
diff --git a/examples/ui-demo/src/components/shared/7702/useTransaction.ts b/examples/ui-demo/src/components/shared/7702/useTransaction.ts
new file mode 100644
index 0000000000..87ae171fdf
--- /dev/null
+++ b/examples/ui-demo/src/components/shared/7702/useTransaction.ts
@@ -0,0 +1,104 @@
+import { useState } from "react";
+import { createPublicClient } from "viem";
+import { mekong, splitMekongTransport } from "./transportSetup";
+import {
+ createBundlerClientFromExisting,
+ LocalAccountSigner,
+} from "@aa-sdk/core";
+import { privateKeyToAccount } from "viem/accounts";
+import { send7702UO } from "./demoSend7702UO";
+
+export type TransactionStages = "initial" | "initiating" | "next" | "complete";
+export type TransactionType = {
+ state: TransactionStages;
+ description: string;
+ externalLink: string;
+};
+
+const initialState: TransactionType[] = [
+ {
+ state: "initial",
+ description: "Bought 1 ETH for 4,000 USDC",
+ externalLink: "www.alchemy.com",
+ },
+ {
+ state: "initial",
+ description: "Bought 1 ETH for 3,500 USDC",
+ externalLink: "www.alchemy.com",
+ },
+ {
+ state: "initial",
+ description: "Bought 1 ETH for 4,200 USDC",
+ externalLink: "www.alchemy.com",
+ },
+];
+
+export const useTransactions = () => {
+ const [transactions, setTransactions] =
+ useState(initialState);
+
+ const [isLoading, setIsLoading] = useState(false);
+
+ const handleTransaction = async (transactionIndex: number) => {
+ setTransactions((prev) => {
+ const newState = [...prev];
+ newState[transactionIndex].state = "initiating";
+ if (transactionIndex + 1 < newState.length) {
+ newState[transactionIndex + 1].state = "next";
+ }
+ return newState;
+ });
+ await new Promise((resolve) => setTimeout(resolve, 3000));
+ setTransactions((prev) => {
+ const newState = [...prev];
+ newState[transactionIndex].state = "complete";
+ return newState;
+ });
+ const publicClient = createPublicClient({
+ chain: mekong,
+ transport: splitMekongTransport,
+ });
+ const bundlerClient = createBundlerClientFromExisting(publicClient);
+ const localAccount = privateKeyToAccount(
+ "0x18bec901c0253fbb203d3423dada59eb720c68f34935185de43d161b0524404b"
+ );
+ send7702UO(
+ bundlerClient,
+ splitMekongTransport,
+ new LocalAccountSigner(localAccount)
+ );
+ };
+ // Mock method to fire transactions for 7702
+ const handleTransactions = async () => {
+ console.log({ initialState });
+ // initial state is mutated
+ setIsLoading(true);
+ setTransactions([
+ {
+ state: "initial",
+ description: "Bought 1 ETH for 4,000 USDC",
+ externalLink: "www.alchemy.com",
+ },
+ {
+ state: "initial",
+ description: "Bought 1 ETH for 3,500 USDC",
+ externalLink: "www.alchemy.com",
+ },
+ {
+ state: "initial",
+ description: "Bought 1 ETH for 4,200 USDC",
+ externalLink: "www.alchemy.com",
+ },
+ ]);
+ for (let i = 0; i < transactions.length; i++) {
+ await handleTransaction(i);
+ }
+ setIsLoading(false);
+ };
+
+ return {
+ transactions,
+ handleTransactions,
+ isLoading,
+ };
+};
diff --git a/examples/ui-demo/src/components/shared/WalletTypeSwitch.tsx b/examples/ui-demo/src/components/shared/WalletTypeSwitch.tsx
new file mode 100644
index 0000000000..9b43192654
--- /dev/null
+++ b/examples/ui-demo/src/components/shared/WalletTypeSwitch.tsx
@@ -0,0 +1,53 @@
+"use client";
+
+import { Root, Thumb } from "@radix-ui/react-switch";
+import { forwardRef, ElementRef, ComponentPropsWithoutRef } from "react";
+
+import { cn } from "@/lib/utils";
+
+const selectedStyles = "text-[#475569]";
+const unselectedStyles = "text-[#020617]";
+
+const WalletTypeSwitch = forwardRef<
+ ElementRef,
+ ComponentPropsWithoutRef
+>(({ className, checked, ...props }, ref) => (
+
+
+
+
+
+
+ Hybrid account (7702)
+
+
+
+
+));
+WalletTypeSwitch.displayName = Root.displayName;
+
+export { WalletTypeSwitch };
diff --git a/examples/ui-demo/src/components/shared/user-connection-avatar/UserConnectionDetails.tsx b/examples/ui-demo/src/components/shared/user-connection-avatar/UserConnectionDetails.tsx
index 4384f19854..255161a128 100644
--- a/examples/ui-demo/src/components/shared/user-connection-avatar/UserConnectionDetails.tsx
+++ b/examples/ui-demo/src/components/shared/user-connection-avatar/UserConnectionDetails.tsx
@@ -1,3 +1,4 @@
+import { WalletTypes } from "@/app/config";
import { ExternalLinkIcon } from "@/components/icons/external-link";
import { LogoutIcon } from "@/components/icons/logout";
import { DeploymentStatusIndicator } from "@/components/shared/DeploymentStatusIndicator";
@@ -15,8 +16,12 @@ export function UserConnectionDetails({
const user = useUser();
const signer = useSigner();
const { logout } = useLogout();
- const { theme, primaryColor } = useConfigStore(
- ({ ui: { theme, primaryColor } }) => ({ theme, primaryColor })
+ const { theme, primaryColor, walletType } = useConfigStore(
+ ({ ui: { theme, primaryColor }, walletType }) => ({
+ theme,
+ primaryColor,
+ walletType,
+ })
);
const scaAccount = useAccount({ type: "LightAccount" });
@@ -69,40 +74,60 @@ export function UserConnectionDetails({
{/* Smart Account */}
- Smart account
+ {walletType === WalletTypes.smart ? "Smart account" : "Address"}
- {/* Status */}
-
-
Status
-
-
-
- {deploymentStatus ? "Deployed" : "Not deployed"}
-
-
-
- {/* Signer */}
-
-
-
- Signer
-
-
-
+
+ {walletType === WalletTypes.smart ? (
+ <>
+ {/* Status */}
+
+
Status
+
+
+
+ {deploymentStatus ? "Deployed" : "Not deployed"}
+
+
-
+ {/* Signer */}
+
+
+
+ >
+ ) : (
+
+
+ Delegated to
+
+
+
+
+ None
+
+
+
+ )}
{/* Logout */}
diff --git a/examples/ui-demo/src/state/store.tsx b/examples/ui-demo/src/state/store.tsx
index 6e588ed3cc..e99db24681 100644
--- a/examples/ui-demo/src/state/store.tsx
+++ b/examples/ui-demo/src/state/store.tsx
@@ -1,4 +1,4 @@
-import { Config, DEFAULT_CONFIG } from "@/app/config";
+import { Config, DEFAULT_CONFIG, WalletTypes } from "@/app/config";
import { getSectionsForConfig } from "@/app/sections";
import { AuthCardHeader } from "@/components/shared/AuthCardHeader";
import { cookieStorage, parseCookie } from "@account-kit/core";
@@ -49,6 +49,7 @@ export type DemoState = Config & {
) => void;
setTheme: (theme: Config["ui"]["theme"]) => void;
setSupportUrl: (url: string) => void;
+ setWalletType: (walletType: WalletTypes) => void;
};
export const createDemoStore = (initialConfig: Config = DEFAULT_CONFIG) => {
@@ -68,6 +69,7 @@ export const createDemoStore = (initialConfig: Config = DEFAULT_CONFIG) => {
setTheme,
setNftTransferred,
nftTransferred,
+ setWalletType,
...config
}) => config,
skipHydration: true,
@@ -141,6 +143,11 @@ function createInitialState(
},
}));
},
+ setWalletType: (walletType: WalletTypes) => {
+ set(() => ({
+ walletType,
+ }));
+ },
});
}
diff --git a/examples/ui-demo/tailwind.config.ts b/examples/ui-demo/tailwind.config.ts
index c69cbb7552..289f5a047b 100644
--- a/examples/ui-demo/tailwind.config.ts
+++ b/examples/ui-demo/tailwind.config.ts
@@ -104,6 +104,10 @@ const config = {
backgroundImage: {
"bg-main": "url('/images/bg-main.webp')",
},
+ boxShadow: {
+ smallCard:
+ "0px 50px 50px 0px rgba(0, 0, 0, 0.09), 0px 12px 27px 0px rgba(0, 0, 0, 0.10)",
+ },
},
},
plugins: [require("tailwindcss-animate"), require("tailwind-scrollbar")],