Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add asChild prop to UI components #6110

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/funny-taxis-grow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"thirdweb": patch
---

allow passing `asChild` for most ui components
2 changes: 1 addition & 1 deletion apps/dashboard/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
"@radix-ui/react-radio-group": "^1.2.2",
"@radix-ui/react-select": "^2.1.5",
"@radix-ui/react-separator": "^1.1.1",
"@radix-ui/react-slot": "^1.1.1",
"@radix-ui/react-slot": "1.1.1",
"@radix-ui/react-switch": "^1.1.2",
"@radix-ui/react-tooltip": "1.1.7",
"@sentry/nextjs": "8.52.0",
Expand Down
2 changes: 1 addition & 1 deletion apps/playground-web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"@radix-ui/react-scroll-area": "^1.2.2",
"@radix-ui/react-select": "^2.1.5",
"@radix-ui/react-separator": "^1.1.1",
"@radix-ui/react-slot": "^1.1.1",
"@radix-ui/react-slot": "1.1.1",
"@radix-ui/react-switch": "^1.1.2",
"@radix-ui/react-tabs": "^1.1.2",
"@radix-ui/react-tooltip": "1.1.7",
Expand Down
2 changes: 1 addition & 1 deletion apps/portal/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"@radix-ui/react-dialog": "1.1.5",
"@radix-ui/react-dropdown-menu": "^2.1.5",
"@radix-ui/react-select": "^2.1.5",
"@radix-ui/react-slot": "^1.1.1",
"@radix-ui/react-slot": "1.1.1",
"@radix-ui/react-tabs": "^1.1.2",
"@tanstack/react-query": "5.65.1",
"@tryghost/content-api": "^1.11.21",
Expand Down
2 changes: 1 addition & 1 deletion apps/wallet-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"@radix-ui/react-dialog": "1.1.5",
"@radix-ui/react-label": "^2.1.1",
"@radix-ui/react-popover": "^1.1.5",
"@radix-ui/react-slot": "^1.1.1",
"@radix-ui/react-slot": "1.1.1",
"@tanstack/react-query": "5.65.1",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
Expand Down
77 changes: 20 additions & 57 deletions packages/thirdweb/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -132,63 +132,25 @@
},
"typesVersions": {
"*": {
"adapters/*": [
"./dist/types/exports/adapters/*.d.ts"
],
"auth": [
"./dist/types/exports/auth.d.ts"
],
"chains": [
"./dist/types/exports/chains.d.ts"
],
"contract": [
"./dist/types/exports/contract.d.ts"
],
"deploys": [
"./dist/types/exports/deploys.d.ts"
],
"event": [
"./dist/types/exports/event.d.ts"
],
"extensions/*": [
"./dist/types/exports/extensions/*.d.ts"
],
"pay": [
"./dist/types/exports/pay.d.ts"
],
"react": [
"./dist/types/exports/react.d.ts"
],
"react-native": [
"./dist/types/exports/react-native.d.ts"
],
"rpc": [
"./dist/types/exports/rpc.d.ts"
],
"storage": [
"./dist/types/exports/storage.d.ts"
],
"transaction": [
"./dist/types/exports/transaction.d.ts"
],
"utils": [
"./dist/types/exports/utils.d.ts"
],
"wallets": [
"./dist/types/exports/wallets.d.ts"
],
"wallets/*": [
"./dist/types/exports/wallets/*.d.ts"
],
"modules": [
"./dist/types/exports/modules.d.ts"
],
"social": [
"./dist/types/exports/social.d.ts"
],
"ai": [
"./dist/types/exports/ai.d.ts"
]
"adapters/*": ["./dist/types/exports/adapters/*.d.ts"],
"auth": ["./dist/types/exports/auth.d.ts"],
"chains": ["./dist/types/exports/chains.d.ts"],
"contract": ["./dist/types/exports/contract.d.ts"],
"deploys": ["./dist/types/exports/deploys.d.ts"],
"event": ["./dist/types/exports/event.d.ts"],
"extensions/*": ["./dist/types/exports/extensions/*.d.ts"],
"pay": ["./dist/types/exports/pay.d.ts"],
"react": ["./dist/types/exports/react.d.ts"],
"react-native": ["./dist/types/exports/react-native.d.ts"],
"rpc": ["./dist/types/exports/rpc.d.ts"],
"storage": ["./dist/types/exports/storage.d.ts"],
"transaction": ["./dist/types/exports/transaction.d.ts"],
"utils": ["./dist/types/exports/utils.d.ts"],
"wallets": ["./dist/types/exports/wallets.d.ts"],
"wallets/*": ["./dist/types/exports/wallets/*.d.ts"],
"modules": ["./dist/types/exports/modules.d.ts"],
"social": ["./dist/types/exports/social.d.ts"],
"ai": ["./dist/types/exports/ai.d.ts"]
}
},
"browser": {
Expand Down Expand Up @@ -217,6 +179,7 @@
"@radix-ui/react-dialog": "1.1.5",
"@radix-ui/react-focus-scope": "1.1.1",
"@radix-ui/react-icons": "1.3.2",
"@radix-ui/react-slot": "1.1.1",
graphite-app[bot] marked this conversation as resolved.
Show resolved Hide resolved
"@radix-ui/react-tooltip": "1.1.7",
"@tanstack/react-query": "5.65.1",
"@walletconnect/ethereum-provider": "2.17.5",
Expand Down
8 changes: 6 additions & 2 deletions packages/thirdweb/src/react/web/ui/SiteLink.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"use client";
import * as Slot from "@radix-ui/react-slot";
import { useQuery } from "@tanstack/react-query";
import type { ThirdwebClient } from "../../../client/client.js";
import { getLastAuthProvider } from "../../../react/core/utils/storage.js";
Expand Down Expand Up @@ -34,8 +35,10 @@ export function SiteLink({
client,
ecosystem,
children,
asChild,
...props
}: {
asChild?: boolean;
href: string;
client: ThirdwebClient;
ecosystem?: Ecosystem;
Expand Down Expand Up @@ -82,9 +85,10 @@ export function SiteLink({
url.searchParams.set("authCookie", authCookie);
}

const Comp = asChild ? Slot.Root : "a";
return (
<a href={encodeURI(url.toString())} {...props}>
<Comp href={encodeURI(url.toString())} {...props}>
{children}
</a>
</Comp>
);
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"use client";

import * as Slot from "@radix-ui/react-slot";
import { useAccountContext } from "../../../../core/account/provider.js";

/**
Expand All @@ -8,6 +9,7 @@ import { useAccountContext } from "../../../../core/account/provider.js";
*/
export interface AccountAddressProps
extends Omit<React.HTMLAttributes<HTMLSpanElement>, "children"> {
asChild?: boolean;
/**
* The function used to transform (format) the wallet address
* Specifically useful for shortening the wallet.
Expand Down Expand Up @@ -56,9 +58,11 @@ export interface AccountAddressProps
*/
export function AccountAddress({
formatFn,
asChild,
...restProps
}: AccountAddressProps) {
const { address } = useAccountContext();
const value = formatFn ? formatFn(address) : address;
return <span {...restProps}>{value}</span>;
const Comp = asChild ? Slot.Root : "span";
return <Comp {...restProps}>{value}</Comp>;
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"use client";

import * as Slot from "@radix-ui/react-slot";
import { type UseQueryOptions, useQuery } from "@tanstack/react-query";
import type React from "react";
import type { JSX } from "react";
Expand All @@ -20,6 +21,7 @@ import { useAccountContext } from "../../../../core/account/provider.js";
export interface AccountAvatarProps
extends Omit<React.ImgHTMLAttributes<HTMLImageElement>, "src">,
Omit<ResolveNameOptions, "client" | "address"> {
asChild?: boolean;
/**
* Use this prop to prioritize the social profile that you want to display
* This is useful for a wallet containing multiple social profiles.
Expand Down Expand Up @@ -159,6 +161,7 @@ export function AccountAvatar({
loadingComponent,
fallbackComponent,
queryOptions,
asChild,
...restProps
}: AccountAvatarProps) {
const { address, client } = useAccountContext();
Expand Down Expand Up @@ -222,5 +225,6 @@ export function AccountAvatar({
return fallbackComponent || null;
}

return <img src={avatarQuery.data} {...restProps} alt={restProps.alt} />;
const Comp = asChild ? Slot.Root : "img";
return <Comp src={avatarQuery.data} {...restProps} alt={restProps.alt} />;
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"use client";

import * as Slot from "@radix-ui/react-slot";
import { type UseQueryOptions, useQuery } from "@tanstack/react-query";
import type React from "react";
import type { JSX } from "react";
Expand All @@ -22,6 +23,7 @@ import { formatAccountTokenBalance } from "../../../../core/utils/account.js";
*/
export interface AccountBalanceProps
extends Omit<React.HTMLAttributes<HTMLSpanElement>, "children"> {
asChild?: boolean;
/**
* The network to fetch balance on
* If not passed, the component will use the current chain that the wallet is connected to (`useActiveWalletChain()`)
Expand Down Expand Up @@ -166,6 +168,7 @@ export function AccountBalance({
queryOptions,
formatFn,
showBalanceInFiat,
asChild,
...restProps
}: AccountBalanceProps) {
const { address, client } = useAccountContext();
Expand Down Expand Up @@ -212,12 +215,13 @@ export function AccountBalance({
);
}

const Comp = asChild ? Slot.Root : "span";
return (
<span {...restProps}>
<Comp {...restProps}>
{formatAccountTokenBalance({
...balanceQuery.data,
decimals: balanceQuery.data.balance < 1 ? 3 : 2,
})}
</span>
</Comp>
);
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"use client";

import * as Slot from "@radix-ui/react-slot";
import { type UseQueryOptions, useQuery } from "@tanstack/react-query";
import type React from "react";
import type { JSX } from "react";
Expand All @@ -19,6 +20,7 @@ import { useAccountContext } from "../../../../core/account/provider.js";
export interface AccountNameProps
extends Omit<React.HTMLAttributes<HTMLSpanElement>, "children">,
Omit<ResolveNameOptions, "client" | "address"> {
asChild?: boolean;
/**
* A function used to transform (format) the name of the account.
* it should take in a string and output a string.
Expand Down Expand Up @@ -134,6 +136,7 @@ export function AccountName({
queryOptions,
loadingComponent,
fallbackComponent,
asChild,
...restProps
}: AccountNameProps) {
const { address, client } = useAccountContext();
Expand Down Expand Up @@ -177,5 +180,6 @@ export function AccountName({
return fallbackComponent || null;
}

return <span {...restProps}>{nameQuery.data}</span>;
const Comp = asChild ? Slot.Root : "span";
return <Comp {...restProps}>{nameQuery.data}</Comp>;
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"use client";

import * as Slot from "@radix-ui/react-slot";
import { type UseQueryOptions, useQuery } from "@tanstack/react-query";
import type { JSX } from "react";
import type { Chain } from "../../../../../chains/types.js";
Expand All @@ -16,6 +17,7 @@ import { useChainContext } from "./provider.js";
*/
export interface ChainIconProps
extends Omit<React.ImgHTMLAttributes<HTMLImageElement>, "src"> {
asChild?: boolean;
/**
* You need a ThirdwebClient to resolve the icon which is hosted on IPFS.
* (since most chain icons are hosted on IPFS, loading them via thirdweb gateway will ensure better performance)
Expand Down Expand Up @@ -119,6 +121,7 @@ export function ChainIcon({
fallbackComponent,
queryOptions,
client,
asChild,
...restProps
}: ChainIconProps) {
const { chain } = useChainContext();
Expand All @@ -136,7 +139,8 @@ export function ChainIcon({
return fallbackComponent || null;
}

return <img src={iconQuery.data} {...restProps} alt={restProps.alt} />;
const Comp = asChild ? Slot.Root : "img";
return <Comp src={iconQuery.data} {...restProps} alt={restProps.alt} />;
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"use client";

import * as Slot from "@radix-ui/react-slot";
import { type UseQueryOptions, useQuery } from "@tanstack/react-query";
import type React from "react";
import type { JSX } from "react";
Expand All @@ -15,6 +16,7 @@ import { useChainContext } from "./provider.js";
*/
export interface ChainNameProps
extends Omit<React.HTMLAttributes<HTMLSpanElement>, "children"> {
asChild?: boolean;
/**
* This prop can be a string or a (async) function that resolves to a string, representing the name of the chain
* This is particularly useful if you already have a way to fetch the chain name.
Expand Down Expand Up @@ -153,6 +155,7 @@ export function ChainName({
loadingComponent,
fallbackComponent,
queryOptions,
asChild,
...restProps
}: ChainNameProps) {
const { chain } = useChainContext();
Expand All @@ -172,7 +175,8 @@ export function ChainName({

const displayValue = formatFn ? formatFn(nameQuery.data) : nameQuery.data;

return <span {...restProps}>{displayValue}</span>;
const Comp = asChild ? Slot.Root : "span";
return <Comp {...restProps}>{displayValue}</Comp>;
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"use client";

import * as Slot from "@radix-ui/react-slot";
import { type UseQueryOptions, useQuery } from "@tanstack/react-query";
import type { JSX } from "react";
import type { ThirdwebContract } from "../../../../../contract/contract.js";
Expand All @@ -9,6 +10,7 @@ import { getNFTInfo } from "./utils.js";

export interface NFTDescriptionProps
extends Omit<React.HTMLAttributes<HTMLSpanElement>, "children"> {
asChild?: boolean;
loadingComponent?: JSX.Element;
fallbackComponent?: JSX.Element;
/**
Expand Down Expand Up @@ -88,6 +90,7 @@ export function NFTDescription({
fallbackComponent,
queryOptions,
descriptionResolver,
asChild,
...restProps
}: NFTDescriptionProps) {
const { contract, tokenId } = useNFTContext();
Expand Down Expand Up @@ -119,7 +122,8 @@ export function NFTDescription({
return fallbackComponent || null;
}

return <span {...restProps}>{descQuery.data}</span>;
const Comp = asChild ? Slot.Root : "span";
return <Comp {...restProps}>{descQuery.data}</Comp>;
}

/**
Expand Down
Loading
Loading