{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "perspective-grid", "title": "Perspective Grid", "description": "A 3D-perspective grid that tilts on hover.", "dependencies": [ "motion" ], "files": [ { "path": "registry/new-york/components/perspective-grid/perspective-grid.tsx", "type": "registry:component", "content": "\"use client\";\n\nimport React, { useState } from \"react\";\nimport { motion, type Variants } from \"motion/react\";\nimport { cn } from \"@/lib/utils\";\n\nexport interface Chain {\n id: number;\n name: string;\n symbol: string;\n logo?: string;\n}\n\nconst defaultChains: Chain[] = [\n { id: 1, name: \"Bitcoin\", symbol: \"BTC\", logo: \"/assets/chains/bitcoin.png\" },\n {\n id: 2,\n name: \"Ethereum\",\n symbol: \"ETH\",\n logo: \"/assets/chains/ethereum.png\",\n },\n { id: 3, name: \"BNB Chain\", symbol: \"BNB\", logo: \"/assets/chains/bnb.png\" },\n { id: 4, name: \"Solana\", symbol: \"SOL\", logo: \"/assets/chains/solana.png\" },\n { id: 5, name: \"Polygon\", symbol: \"POL\", logo: \"/assets/chains/polygon.png\" },\n {\n id: 6,\n name: \"Avalanche\",\n symbol: \"AVAX\",\n logo: \"/assets/chains/avalanche.png\",\n },\n {\n id: 7,\n name: \"Arbitrum\",\n symbol: \"ARB\",\n logo: \"/assets/chains/arbitrum.png\",\n },\n {\n id: 8,\n name: \"Optimism\",\n symbol: \"OP\",\n logo: \"/assets/chains/optimism.png\",\n },\n { id: 9, name: \"Base\", symbol: \"BASE\", logo: \"/assets/chains/base.png\" },\n { id: 10, name: \"Sui\", symbol: \"SUI\", logo: \"/assets/chains/sui.png\" },\n { id: 11, name: \"Aptos\", symbol: \"APT\", logo: \"/assets/chains/aptos.png\" },\n { id: 12, name: \"Cosmos\", symbol: \"ATOM\", logo: \"/assets/chains/cosmos.png\" },\n {\n id: 13,\n name: \"Polkadot\",\n symbol: \"DOT\",\n logo: \"/assets/chains/polkadot.png\",\n },\n {\n id: 14,\n name: \"Near Protocol\",\n symbol: \"NEAR\",\n logo: \"/assets/chains/near.png\",\n },\n { id: 15, name: \"Tron\", symbol: \"TRX\", logo: \"/assets/chains/tron.png\" },\n {\n id: 16,\n name: \"Filecoin\",\n symbol: \"FIL\",\n logo: \"/assets/chains/filecoin.png\",\n },\n {\n id: 17,\n name: \"Celestia\",\n symbol: \"TIA\",\n logo: \"/assets/chains/celestia.png\",\n },\n {\n id: 18,\n name: \"Injective\",\n symbol: \"INJ\",\n logo: \"/assets/chains/injective.png\",\n },\n {\n id: 19,\n name: \"Cardano\",\n symbol: \"ADA\",\n logo: \"/assets/chains/cardano.png\",\n },\n {\n id: 20,\n name: \"Toncoin\",\n symbol: \"TON\",\n logo: \"/assets/chains/toncoin.png\",\n },\n {\n id: 21,\n name: \"Starknet\",\n symbol: \"STRK\",\n logo: \"/assets/chains/starknet.png\",\n },\n { id: 22, name: \"zkSync\", symbol: \"ZK\", logo: \"/assets/chains/zksync.png\" },\n {\n id: 23,\n name: \"Internet Computer\",\n symbol: \"ICP\",\n logo: \"/assets/chains/icp.png\",\n },\n { id: 24, name: \"Sei\", symbol: \"SEI\", logo: \"/assets/chains/sei.png\" },\n];\n\nconst chainColors: Record = {\n BTC: \"#f7931a\",\n ETH: \"#627eea\",\n BNB: \"#f0b90b\",\n SOL: \"#9945ff\",\n POL: \"#8247e5\",\n AVAX: \"#e84142\",\n ARB: \"#2d374b\",\n OP: \"#ff0420\",\n BASE: \"#0052ff\",\n SUI: \"#4da2ff\",\n APT: \"#00bfa5\",\n ATOM: \"#2e3148\",\n DOT: \"#e6007a\",\n NEAR: \"#000000\",\n TRX: \"#ef0027\",\n FIL: \"#0090ff\",\n TIA: \"#7b2fe9\",\n INJ: \"#00f2fe\",\n ADA: \"#0033ad\",\n TON: \"#0098ea\",\n STRK: \"#08a4d4\",\n ZK: \"#4c8eff\",\n ICP: \"#3b00b9\",\n SEI: \"#8c1c40\",\n};\n\nconst containerVariants: Variants = {\n hidden: {},\n visible: {\n transition: { staggerChildren: 0.04 },\n },\n};\n\nconst itemVariants: Variants = {\n hidden: { opacity: 0, y: 24, scale: 0.9 },\n visible: {\n opacity: 1,\n y: 0,\n scale: 1,\n transition: { type: \"spring\", stiffness: 300, damping: 24 },\n },\n};\n\nfunction ChainCard({ chain, variants }: { chain: Chain; variants?: Variants }) {\n const [imgFailed, setImgFailed] = useState(false);\n\n return (\n \n \n\n
\n {chain.logo && !imgFailed ? (\n // eslint-disable-next-line @next/next/no-img-element\n setImgFailed(true)}\n />\n ) : (\n \n {chain.symbol}\n
\n )}\n \n \n );\n}\n\nexport interface PerspectiveGridProps {\n chains?: Chain[];\n title?: React.ReactNode;\n subtitle?: React.ReactNode;\n className?: string;\n gridClassName?: string;\n}\n\nexport default function PerspectiveGrid({\n chains = defaultChains,\n title = \"Any transaction on any chain,
Aside executes it for you.\",\n subtitle = \"Multi-chain ecosystem\",\n className,\n gridClassName,\n}: PerspectiveGridProps) {\n return (\n \n
\n \n

\n {subtitle} >\n

\n

\n {typeof title === \"string\"\n ? title.split(\"
\").map((part, i) => (\n \n {i > 0 &&
}\n {part}\n
\n ))\n : title}\n

\n \n\n \n \n {chains.map((chain) => (\n \n ))}\n \n
\n \n \n );\n}\n" } ], "type": "registry:component" }