From f76cbe782b55f4a95eb727292068cc71d195a96f Mon Sep 17 00:00:00 2001 From: Vitor Date: Tue, 12 Dec 2023 13:12:56 -0300 Subject: [PATCH] feat: add network selection --- apps/www/__registry__/index.tsx | 21 ++++ apps/www/config/docs.ts | 5 + .../docs/components/network-selection.mdx | 58 +++++++++++ apps/www/public/registry/index.json | 20 ++++ .../styles/default/dropdown-menu.json | 3 +- .../styles/default/network-selection.json | 16 +++ .../default/buidl/network-selection.tsx | 99 +++++++++++++++++++ .../example/network-selection-demo.tsx | 18 ++++ apps/www/registry/registry.ts | 18 ++++ 9 files changed, 256 insertions(+), 2 deletions(-) create mode 100644 apps/www/content/docs/components/network-selection.mdx create mode 100644 apps/www/public/registry/styles/default/network-selection.json create mode 100644 apps/www/registry/default/buidl/network-selection.tsx create mode 100644 apps/www/registry/default/example/network-selection-demo.tsx diff --git a/apps/www/__registry__/index.tsx b/apps/www/__registry__/index.tsx index d81acf8..2a3dbbf 100644 --- a/apps/www/__registry__/index.tsx +++ b/apps/www/__registry__/index.tsx @@ -229,6 +229,13 @@ export const Index: Record = { component: React.lazy(() => import("@/registry/default/buidl/error-message")), files: ["registry/default/buidl/error-message.tsx"], }, + "network-selection": { + name: "network-selection", + type: "components:buidl", + registryDependencies: ["dropdown-menu"], + component: React.lazy(() => import("@/registry/default/buidl/network-selection")), + files: ["registry/default/buidl/network-selection.tsx"], + }, "button": { name: "button", type: "components:ui", @@ -285,6 +292,13 @@ export const Index: Record = { component: React.lazy(() => import("@/registry/default/ui/skeleton")), files: ["registry/default/ui/skeleton.tsx"], }, + "dropdown-menu": { + name: "dropdown-menu", + type: "components:ui", + registryDependencies: undefined, + component: React.lazy(() => import("@/registry/default/ui/dropdown-menu")), + files: ["registry/default/ui/dropdown-menu.tsx"], + }, "nonce-demo": { name: "nonce-demo", type: "components:example", @@ -516,5 +530,12 @@ export const Index: Record = { component: React.lazy(() => import("@/registry/default/example/card-with-form")), files: ["registry/default/example/card-with-form.tsx"], }, + "network-selection-demo": { + name: "network-selection-demo", + type: "components:example", + registryDependencies: ["network-selection"], + component: React.lazy(() => import("@/registry/default/example/network-selection-demo")), + files: ["registry/default/example/network-selection-demo.tsx"], + }, }, } diff --git a/apps/www/config/docs.ts b/apps/www/config/docs.ts index 02411d3..ff6614d 100644 --- a/apps/www/config/docs.ts +++ b/apps/www/config/docs.ts @@ -115,6 +115,11 @@ export const docsConfig: DocsConfig = { href: "/docs/components/is-wallet-disconnected", items: [], }, + { + title: "Network Selection", + href: "/docs/components/network-selection", + items: [], + }, ], }, { diff --git a/apps/www/content/docs/components/network-selection.mdx b/apps/www/content/docs/components/network-selection.mdx new file mode 100644 index 0000000..9f46f6c --- /dev/null +++ b/apps/www/content/docs/components/network-selection.mdx @@ -0,0 +1,58 @@ +--- +title: Network Selection +description: Select a network to connect to. +component: true +wagmi: + link: https://wagmi.sh/react/hooks/useSwitchNetwork +--- + + + +## Installation + + + + + CLI + Manual + + + + +```bash +npx buidl-cli@latest add network-selection +``` + + + + + + + +Install the following shadcn/ui components: + +- [Button](https://ui.shadcn.com/docs/components/button) +- [DropdownMenu](https://ui.shadcn.com/docs/components/dropdown-menu) + +Copy and paste the following code into your project. + + + + + + + + + +## Usage + +```tsx +import { NetworkSelection } from "@/registry/default/buidl/network-selection" +``` + +```tsx + +``` diff --git a/apps/www/public/registry/index.json b/apps/www/public/registry/index.json index 07b5afe..b795649 100644 --- a/apps/www/public/registry/index.json +++ b/apps/www/public/registry/index.json @@ -435,6 +435,19 @@ ], "type": "components:buidl" }, + { + "name": "network-selection", + "dependencies": [ + "wagmi" + ], + "registryDependencies": [ + "dropdown-menu" + ], + "files": [ + "buidl/network-selection.tsx" + ], + "type": "components:buidl" + }, { "name": "button", "dependencies": [ @@ -504,5 +517,12 @@ "ui/skeleton.tsx" ], "type": "components:ui" + }, + { + "name": "dropdown-menu", + "files": [ + "ui/dropdown-menu.tsx" + ], + "type": "components:ui" } ] \ No newline at end of file diff --git a/apps/www/public/registry/styles/default/dropdown-menu.json b/apps/www/public/registry/styles/default/dropdown-menu.json index 347981c..5f5e736 100644 --- a/apps/www/public/registry/styles/default/dropdown-menu.json +++ b/apps/www/public/registry/styles/default/dropdown-menu.json @@ -1,6 +1,5 @@ { "name": "dropdown-menu", - "dependencies": ["@radix-ui/react-dropdown-menu"], "files": [ { "name": "dropdown-menu.tsx", @@ -8,4 +7,4 @@ } ], "type": "components:ui" -} +} \ No newline at end of file diff --git a/apps/www/public/registry/styles/default/network-selection.json b/apps/www/public/registry/styles/default/network-selection.json new file mode 100644 index 0000000..1afe14b --- /dev/null +++ b/apps/www/public/registry/styles/default/network-selection.json @@ -0,0 +1,16 @@ +{ + "name": "network-selection", + "dependencies": [ + "wagmi" + ], + "registryDependencies": [ + "dropdown-menu" + ], + "files": [ + { + "name": "network-selection.tsx", + "content": "import { useState, type HTMLAttributes } from \"react\"\nimport { ChevronDown } from \"lucide-react\"\nimport { Chain, useNetwork, useSwitchNetwork } from \"wagmi\"\nimport {\n arbitrum,\n base,\n gnosis,\n mainnet,\n optimism,\n polygon,\n} from \"wagmi/chains\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Button } from \"@/registry/default/ui/button\"\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from \"@/registry/default/ui/dropdown-menu\"\n\nconst defaultChains = [arbitrum, base, gnosis, mainnet, optimism, polygon]\n\ninterface NetworkSelectionProps extends HTMLAttributes {\n chainId?: number\n useCurrentNetwork?: boolean\n initialChainId?: number\n selectNetworkLabel?: string\n chains?: Chain[]\n onValueChange?: (chainId: number) => void\n}\n\nexport const NetworkSelection = ({\n className,\n selectNetworkLabel = \"Select Network\",\n useCurrentNetwork = true,\n chains = defaultChains,\n initialChainId,\n onValueChange,\n ...props\n}: NetworkSelectionProps) => {\n const [selectedChain, setSelectedChain] = useState(\n chains.find((chain) => chain.id === initialChainId) || chains[0]\n )\n const { chain } = useNetwork()\n const { switchNetwork } = useSwitchNetwork()\n\n const handleSwitchNetwork = (chain: Chain) => {\n if (useCurrentNetwork) {\n switchNetwork?.(chain.id)\n } else {\n setSelectedChain(chain)\n }\n onValueChange?.(chain.id)\n }\n\n return (\n
\n \n \n \n \n \n {selectNetworkLabel}\n \n {chains.length > 0 &&\n chains.map((chain) => (\n handleSwitchNetwork(chain)}\n >\n \n {chain.name} ({chain.id})\n \n \n ))}\n \n \n
\n )\n}\n" + } + ], + "type": "components:buidl" +} \ No newline at end of file diff --git a/apps/www/registry/default/buidl/network-selection.tsx b/apps/www/registry/default/buidl/network-selection.tsx new file mode 100644 index 0000000..828c6c4 --- /dev/null +++ b/apps/www/registry/default/buidl/network-selection.tsx @@ -0,0 +1,99 @@ +import { useState, type HTMLAttributes } from "react" +import { ChevronDown } from "lucide-react" +import { Chain, useNetwork, useSwitchNetwork } from "wagmi" +import { + arbitrum, + base, + gnosis, + mainnet, + optimism, + polygon, +} from "wagmi/chains" + +import { cn } from "@/lib/utils" +import { Button } from "@/registry/default/ui/button" +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuLabel, + DropdownMenuSeparator, + DropdownMenuTrigger, +} from "@/registry/default/ui/dropdown-menu" + +const defaultChains = [arbitrum, base, gnosis, mainnet, optimism, polygon] + +interface NetworkSelectionProps extends HTMLAttributes { + chainId?: number + useCurrentNetwork?: boolean + initialChainId?: number + selectNetworkLabel?: string + chains?: Chain[] + onValueChange?: (chainId: number) => void +} + +export const NetworkSelection = ({ + className, + selectNetworkLabel = "Select Network", + useCurrentNetwork = true, + chains = defaultChains, + initialChainId, + onValueChange, + ...props +}: NetworkSelectionProps) => { + const [selectedChain, setSelectedChain] = useState( + chains.find((chain) => chain.id === initialChainId) || chains[0] + ) + const { chain } = useNetwork() + const { switchNetwork } = useSwitchNetwork() + + const handleSwitchNetwork = (chain: Chain) => { + if (useCurrentNetwork) { + switchNetwork?.(chain.id) + } else { + setSelectedChain(chain) + } + onValueChange?.(chain.id) + } + + return ( +
+ + + + + + {selectNetworkLabel} + + {chains.length > 0 && + chains.map((chain) => ( + handleSwitchNetwork(chain)} + > + + {chain.name} ({chain.id}) + + + ))} + + +
+ ) +} diff --git a/apps/www/registry/default/example/network-selection-demo.tsx b/apps/www/registry/default/example/network-selection-demo.tsx new file mode 100644 index 0000000..bdb6df3 --- /dev/null +++ b/apps/www/registry/default/example/network-selection-demo.tsx @@ -0,0 +1,18 @@ +import { IsWalletConnected } from "@/registry/default/buidl/is-wallet-connected" +import { IsWalletDisconnected } from "@/registry/default/buidl/is-wallet-disconnected" +import { WalletConnect } from "@/registry/default/buidl/wallet-connect" + +import { NetworkSelection } from "../buidl/network-selection" + +export default function NetworkSelectionDemo() { + return ( +
+ + + + + + +
+ ) +} diff --git a/apps/www/registry/registry.ts b/apps/www/registry/registry.ts index 9aeeb33..98ecbbe 100644 --- a/apps/www/registry/registry.ts +++ b/apps/www/registry/registry.ts @@ -45,6 +45,11 @@ const ui: Registry = [ type: "components:ui", files: ["ui/skeleton.tsx"], }, + { + name: "dropdown-menu", + type: "components:ui", + files: ["ui/dropdown-menu.tsx"], + }, ] const buidl: Registry = [ @@ -279,6 +284,13 @@ const buidl: Registry = [ dependencies: ["wagmi"], files: ["buidl/error-message.tsx"], }, + { + name: "network-selection", + type: "components:buidl", + dependencies: ["wagmi"], + registryDependencies: ["dropdown-menu"], + files: ["buidl/network-selection.tsx"], + }, ] const example: Registry = [ @@ -480,6 +492,12 @@ const example: Registry = [ registryDependencies: ["button", "card", "input", "label", "select"], files: ["example/card-with-form.tsx"], }, + { + name: "network-selection-demo", + type: "components:example", + registryDependencies: ["button", "network-selection"], + files: ["example/network-selection-demo.tsx"], + }, ] export const registry: Registry = [...buidl, ...ui, ...example]