diff --git a/app/[locale]/layer-2/networks/page.tsx b/app/[locale]/layer-2/networks/page.tsx index e2456436c82..95b03a22235 100644 --- a/app/[locale]/layer-2/networks/page.tsx +++ b/app/[locale]/layer-2/networks/page.tsx @@ -10,7 +10,7 @@ import type { ExtendedRollup, Lang, PageParams } from "@/lib/types" import CalloutSSR from "@/components/CalloutSSR" import { ContentHero, type ContentHeroProps } from "@/components/Hero" import I18nProvider from "@/components/I18nProvider" -import Layer2NetworksTable from "@/components/Layer2NetworksTable/lazy" +import Layer2NetworksTable from "@/components/Layer2NetworksTable" import MainArticle from "@/components/MainArticle" import NetworkMaturity from "@/components/NetworkMaturity" import { ButtonLink } from "@/components/ui/buttons/Button" diff --git a/app/[locale]/wallets/find-wallet/page.tsx b/app/[locale]/wallets/find-wallet/page.tsx index 30697df527c..36d48c53aee 100644 --- a/app/[locale]/wallets/find-wallet/page.tsx +++ b/app/[locale]/wallets/find-wallet/page.tsx @@ -8,7 +8,7 @@ import { import type { Lang, PageParams } from "@/lib/types" import Breadcrumbs from "@/components/Breadcrumbs" -import FindWalletProductTable from "@/components/FindWalletProductTable/lazy" +import FindWalletProductTable from "@/components/FindWalletProductTable" import I18nProvider from "@/components/I18nProvider" import MainArticle from "@/components/MainArticle" diff --git a/src/components/FindWalletProductTable/List.tsx b/src/components/FindWalletProductTable/List.tsx new file mode 100644 index 00000000000..8b72d890299 --- /dev/null +++ b/src/components/FindWalletProductTable/List.tsx @@ -0,0 +1,113 @@ +import { memo, useCallback, useRef, useState } from "react" + +import type { WalletRow } from "@/lib/types" + +import { cn } from "@/lib/utils/cn" +import { trackCustomEvent } from "@/lib/utils/matomo" + +import WalletInfo from "./WalletInfo" + +type RowProps = { + wallet: WalletRow + index: number + open: boolean + visible: boolean + onOpenChange: (open: boolean, wallet: WalletRow) => void + children?: React.ReactNode +} + +const Row = memo(function Row({ + wallet, + index, + open, + visible, + onOpenChange, + children, +}: RowProps) { + const handleToggle = useCallback( + (e: React.SyntheticEvent) => { + onOpenChange(e.currentTarget.open, wallet) + }, + [onOpenChange, wallet] + ) + return ( +
+ + + + {open &&
{children}
} +
+ ) +}) + +type ListProps = { + data: WalletRow[] + // Rows whose id is not in `matchedIds` are display:none. Avoids + // mount/unmount churn on filter changes. + matchedIds: Set + renderSubComponent: (wallet: WalletRow, listIdx: number) => React.ReactNode + matomoEventCategory: string +} + +const List = ({ + data, + matchedIds, + renderSubComponent, + matomoEventCategory, + ...rest +}: ListProps) => { + const [expanded, setExpanded] = useState>({}) + const previousExpandedRef = useRef>({}) + + const handleOpenChange = useCallback( + (open: boolean, wallet: WalletRow) => { + setExpanded((prev) => ({ ...prev, [wallet.id]: open })) + + if (!open) return + + const expandedOnce = previousExpandedRef.current[wallet.id] + if (!expandedOnce) { + trackCustomEvent({ + eventCategory: matomoEventCategory, + eventAction: "expanded", + eventName: wallet.id, + }) + } + previousExpandedRef.current = { + ...previousExpandedRef.current, + [wallet.id]: true, + } + }, + [matomoEventCategory] + ) + + return ( +
+ {data.map((wallet, index) => { + const open = !!expanded[wallet.id] + return ( + + {open && renderSubComponent(wallet, index)} + + ) + })} +
+ ) +} + +export default List diff --git a/src/components/FindWalletProductTable/WalletInfo.tsx b/src/components/FindWalletProductTable/WalletInfo.tsx index 5e00ac5f5c0..f7b84841fca 100644 --- a/src/components/FindWalletProductTable/WalletInfo.tsx +++ b/src/components/FindWalletProductTable/WalletInfo.tsx @@ -8,12 +8,10 @@ import { DevicesIcon, LanguagesIcon } from "@/components/icons/wallets" import { Image } from "@/components/Image" import { SupportedLanguagesTooltip } from "@/components/SupportedLanguagesTooltip" -import { breakpointAsNumber } from "@/lib/utils/screen" import { formatStringList, getWalletPersonas } from "@/lib/utils/wallets" import { NUMBER_OF_SUPPORTED_LANGUAGES_SHOWN } from "@/lib/constants" -import MediaQuery from "../MediaQuery" import { ButtonLink } from "../ui/buttons/Button" import { TagsInlineText } from "../ui/tag" @@ -59,120 +57,79 @@ const WalletInfo = ({ wallet }: WalletInfoProps) => { }, [wallet.supportedLanguages]) return ( -
+
+ {/* Open-state stripe (desktop only), sits in the image-column gutter. */} +