diff --git a/apps/www/__registry__/index.tsx b/apps/www/__registry__/index.tsx index d81acf8..e51e05e 100644 --- a/apps/www/__registry__/index.tsx +++ b/apps/www/__registry__/index.tsx @@ -5,6 +5,13 @@ import * as React from "react" export const Index: Record = { "default": { + "account-input": { + name: "account-input", + type: "components:buidl", + registryDependencies: ["block-explorer-link"], + component: React.lazy(() => import("@/registry/default/buidl/account-input")), + files: ["registry/default/buidl/account-input.tsx"], + }, "address": { name: "address", type: "components:buidl", @@ -299,6 +306,13 @@ export const Index: Record = { component: React.lazy(() => import("@/registry/default/example/address-demo")), files: ["registry/default/example/address-demo.tsx"], }, + "account-input-demo": { + name: "account-input-demo", + type: "components:example", + registryDependencies: ["account-input"], + component: React.lazy(() => import("@/registry/default/example/account-input-demo")), + files: ["registry/default/example/account-input-demo.tsx"], + }, "balance-demo": { name: "balance-demo", type: "components:example", diff --git a/apps/www/config/docs.ts b/apps/www/config/docs.ts index 02411d3..883bd81 100644 --- a/apps/www/config/docs.ts +++ b/apps/www/config/docs.ts @@ -120,6 +120,11 @@ export const docsConfig: DocsConfig = { { title: "Primitives", items: [ + { + title: "Account Input", + href: "/docs/components/account-input", + items: [], + }, { title: "Address", href: "/docs/components/address", diff --git a/apps/www/content/docs/components/account-input.mdx b/apps/www/content/docs/components/account-input.mdx new file mode 100644 index 0000000..fb05d69 --- /dev/null +++ b/apps/www/content/docs/components/account-input.mdx @@ -0,0 +1,62 @@ +--- +title: Account Input +description: Input for Ethereum account or ENS name +component: true +wagmi: + link: https://wagmi.sh/react/hooks/useEnsName +--- + + + +## Installation + + + + + CLI + Manual + + + + +```bash +npx buidl-cli@latest add account-input +``` + + + + + + + +Install the following components: + +- [ErrorMessage](/docs/components/error-message) + +Install the following shadcn/ui components: + +- [Input](https://ui.shadcn.com/docs/components/input) +- [Skeleton](https://ui.shadcn.com/docs/components/skeleton) + +Copy and paste the following code into your project. + + + + + + + + + +## Usage + +```tsx +import { AccountInput } from "@/registry/default/buidl/account-input" +``` + +```tsx + +``` diff --git a/apps/www/public/registry/index.json b/apps/www/public/registry/index.json index 07b5afe..56ebb92 100644 --- a/apps/www/public/registry/index.json +++ b/apps/www/public/registry/index.json @@ -1,4 +1,17 @@ [ + { + "name": "account-input", + "dependencies": [ + "wagmi" + ], + "registryDependencies": [ + "block-explorer-link" + ], + "files": [ + "buidl/account-input.tsx" + ], + "type": "components:buidl" + }, { "name": "address", "dependencies": [ diff --git a/apps/www/public/registry/styles/default/account-input.json b/apps/www/public/registry/styles/default/account-input.json new file mode 100644 index 0000000..8b7a3f0 --- /dev/null +++ b/apps/www/public/registry/styles/default/account-input.json @@ -0,0 +1,16 @@ +{ + "name": "account-input", + "dependencies": [ + "wagmi" + ], + "registryDependencies": [ + "block-explorer-link" + ], + "files": [ + { + "name": "account-input.tsx", + "content": "import { InputHTMLAttributes, forwardRef, useMemo } from \"react\"\nimport { isAddress, type Address } from \"viem\"\nimport { useEnsAddress, useEnsName } from \"wagmi\"\n\nimport { cn } from \"@/lib/utils\"\n\nimport { Input } from \"../ui/input\"\nimport { BlockExplorerLink } from \"./block-explorer-link\"\nimport { EnsAvatar } from \"./ens-avatar\"\n\ninterface AccountInputProps extends InputHTMLAttributes {\n value?: string\n}\n\nconst AccountInput = forwardRef(\n ({ value, className, ...props }, ref) => {\n const isValidAddress = useMemo(\n () => typeof value === \"string\" && isAddress(value),\n [value]\n )\n\n const { data: ensAddress } = useEnsAddress({\n name: value,\n // Resolve ENS only on mainnet\n chainId: 1,\n })\n\n const { data: ensName } = useEnsName({\n address: value as Address | undefined,\n chainId: 1,\n })\n\n return (\n \n \n {(isValidAddress || ensAddress) && value && (\n
\n \n
\n \n
\n \n
\n )}\n {ensAddress && (\n \n {ensAddress.slice(0, 8)}...{ensAddress.slice(-6)}\n \n )}\n {ensName && (\n \n {ensName}\n \n )}\n \n )\n }\n)\n\nAccountInput.displayName = \"AccountInput\"\nexport { AccountInput }\n" + } + ], + "type": "components:buidl" +} \ No newline at end of file diff --git a/apps/www/registry/default/buidl/account-input.tsx b/apps/www/registry/default/buidl/account-input.tsx new file mode 100644 index 0000000..d70b650 --- /dev/null +++ b/apps/www/registry/default/buidl/account-input.tsx @@ -0,0 +1,80 @@ +import { InputHTMLAttributes, forwardRef, useMemo } from "react" +import { isAddress, type Address } from "viem" +import { useEnsAddress, useEnsName } from "wagmi" + +import { cn } from "@/lib/utils" + +import { Input } from "../ui/input" +import { BlockExplorerLink } from "./block-explorer-link" +import { EnsAvatar } from "./ens-avatar" + +interface AccountInputProps extends InputHTMLAttributes { + value?: string +} + +const AccountInput = forwardRef( + ({ value, className, ...props }, ref) => { + const isValidAddress = useMemo( + () => typeof value === "string" && isAddress(value), + [value] + ) + + const { data: ensAddress } = useEnsAddress({ + name: value, + // Resolve ENS only on mainnet + chainId: 1, + }) + + const { data: ensName } = useEnsName({ + address: value as Address | undefined, + chainId: 1, + }) + + return ( +
+ + {(isValidAddress || ensAddress) && value && ( +
+ +
+ +
+
+
+ )} + {ensAddress && ( + + {ensAddress.slice(0, 8)}...{ensAddress.slice(-6)} + + )} + {ensName && ( + + {ensName} + + )} +
+ ) + } +) + +AccountInput.displayName = "AccountInput" +export { AccountInput } diff --git a/apps/www/registry/default/example/account-input-demo.tsx b/apps/www/registry/default/example/account-input-demo.tsx new file mode 100644 index 0000000..6ade3d5 --- /dev/null +++ b/apps/www/registry/default/example/account-input-demo.tsx @@ -0,0 +1,42 @@ +import { useState, useRef, useEffect } from "react" +import { AccountInput } from "@/registry/default/buidl/account-input" + + +export const ADDRESS_EXAMPLE = "0x761d584f1C2d43cBc3F42ECd739701a36dFFAa31" + +export default function AccountInputDemo() { + const inputRefEnsName = useRef(null) + const inputRefEnsAddress = useRef(null) + + const [address, setAddress] = useState() + + useEffect(() => { + if(inputRefEnsName.current) { + inputRefEnsName.current.value = "vitalik.eth" + } + if(inputRefEnsAddress.current) { + inputRefEnsAddress.current.value = "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045" + } + }, []); + return ( +
+

Default

+ setAddress(e.target.value)} + /> + +

Ens Name Resolution

+ + +

Ens Address Resolution

+ +
+ ) +} diff --git a/apps/www/registry/registry.ts b/apps/www/registry/registry.ts index 9aeeb33..6fc23fa 100644 --- a/apps/www/registry/registry.ts +++ b/apps/www/registry/registry.ts @@ -48,6 +48,13 @@ const ui: Registry = [ ] const buidl: Registry = [ + { + name: "account-input", + type: "components:buidl", + dependencies: ["wagmi"], + registryDependencies: ["block-explorer-link"], + files: ["buidl/account-input.tsx"], + }, { name: "address", type: "components:buidl", @@ -294,6 +301,12 @@ const example: Registry = [ registryDependencies: ["address"], files: ["example/address-demo.tsx"], }, + { + name: "account-input-demo", + type: "components:example", + registryDependencies: ["account-input"], + files: ["example/account-input-demo.tsx"], + }, { name: "balance-demo", type: "components:example",