- {feeds.map(({ product }) => (
+ {feeds.map((feed) => (
-
-
{product.display_symbol}
-
-
{product.display_symbol}
-
- {product.description.split("/")[0]}
-
-
-
+
{showPrices && (
-
-
+
+
)}
@@ -238,53 +202,6 @@ const FeaturedFeedsCard = ({
);
-const PriceFeedNameAndIcon = ({ children }: { children: string }) => (
-
-
{children}
-
{children}
-
-);
-
-const PriceFeedIcon = ({ children }: { children: string }) => {
- const firstPart = children.split("/")[0];
- const Icon = firstPart ? (getIcon(firstPart) ?? Generic) : Generic;
-
- return (
-
- );
-};
-
-const PriceFeedName = ({ children }: { children: string }) => {
- const [firstPart, ...parts] = children.split("/");
-
- return (
-
- {firstPart}
- {parts.map((part, i) => (
-
- /
- {part}
-
- ))}
-
- );
-};
-
-const toHex = (value: string) => toHexString(base58.decode(value));
-
-const toTruncatedHex = (value: string) => {
- const hex = toHex(value);
- return `${hex.slice(0, 6)}...${hex.slice(-4)}`;
-};
-
-const toHexString = (byteArray: Uint8Array) =>
- `0x${Array.from(byteArray, (byte) => byte.toString(16).padStart(2, "0")).join("")}`;
-
const getPriceFeeds = async () => {
const data = await client.getData();
const priceFeeds = priceFeedsSchema.parse(
diff --git a/apps/insights/src/components/PriceFeeds/layout.tsx b/apps/insights/src/components/PriceFeeds/layout.tsx
new file mode 100644
index 000000000..276b191a8
--- /dev/null
+++ b/apps/insights/src/components/PriceFeeds/layout.tsx
@@ -0,0 +1,41 @@
+"use client";
+
+import type { ReactNode } from "react";
+
+import { type VariantArg, LayoutTransition } from "../LayoutTransition";
+
+type Props = {
+ children: ReactNode;
+};
+
+export const PriceFeedsLayout = ({ children }: Props) => (
+
({
+ opacity: 0,
+ scale: isGoingToIndex(custom) ? 1.04 : 0.96,
+ }),
+ exit: (custom) => ({
+ opacity: 0,
+ scale: isGoingToIndex(custom) ? 0.96 : 1.04,
+ transition: {
+ scale: { type: "spring", bounce: 0 },
+ },
+ }),
+ }}
+ initial="initial"
+ animate={{
+ opacity: 1,
+ scale: 1,
+ transition: {
+ scale: { type: "spring", bounce: 0 },
+ },
+ }}
+ style={{ transformOrigin: "top" }}
+ exit="exit"
+ >
+ {children}
+
+);
+
+const isGoingToIndex = ({ segment }: VariantArg) => segment === null;
diff --git a/apps/insights/src/components/PriceFeeds/price-feeds-card.tsx b/apps/insights/src/components/PriceFeeds/price-feeds-card.tsx
index cacf5adcf..09795b473 100644
--- a/apps/insights/src/components/PriceFeeds/price-feeds-card.tsx
+++ b/apps/insights/src/components/PriceFeeds/price-feeds-card.tsx
@@ -12,7 +12,7 @@ import { type ReactNode, Suspense, useCallback, useMemo } from "react";
import { useFilter, useCollator } from "react-aria";
import { serialize, useQueryParams } from "./query-params";
-import { SKELETON_WIDTH, LivePrice, LiveConfidence } from "../LivePrices";
+import { SKELETON_WIDTH } from "../LivePrices";
type Props = {
id: string;
@@ -25,8 +25,10 @@ type PriceFeed = {
id: string;
displaySymbol: string;
assetClassAsString: string;
- exponent: number;
- numPublishers: number;
+ exponent: ReactNode;
+ numPublishers: ReactNode;
+ price: ReactNode;
+ confidenceInterval: ReactNode;
priceFeedId: ReactNode;
priceFeedName: ReactNode;
assetClass: ReactNode;
@@ -85,14 +87,10 @@ const ResolvedPriceFeedsCard = ({ priceFeeds, ...props }: Props) => {
);
const rows = useMemo(
() =>
- paginatedFeeds.map(({ id, ...data }) => ({
+ paginatedFeeds.map(({ id, symbol, ...data }) => ({
id,
- href: "#",
- data: {
- ...data,
- price:
,
- confidenceInterval:
,
- },
+ href: `/price-feeds/${encodeURIComponent(symbol)}`,
+ data,
})),
[paginatedFeeds],
);
diff --git a/apps/insights/src/components/Publishers/index.module.scss b/apps/insights/src/components/Publishers/index.module.scss
index 37692bb73..9ab9b38cb 100644
--- a/apps/insights/src/components/Publishers/index.module.scss
+++ b/apps/insights/src/components/Publishers/index.module.scss
@@ -149,21 +149,23 @@
border-radius: theme.border-radius("full");
}
+ .key {
+ margin: 0 -#{theme.button-padding("sm", true)};
+ }
+
.nameAndKey {
display: flex;
flex-flow: column nowrap;
gap: theme.spacing(1);
align-items: flex-start;
- .publisherKey {
- color: theme.color("link", "normal");
- font-weight: theme.font-weight("medium");
- font-size: theme.font-size("xxs");
+ .name {
+ color: theme.color("heading");
}
- }
- .name {
- color: theme.color("heading");
+ .key {
+ margin: 0 -#{theme.button-padding("xs", true)};
+ }
}
&[data-is-undisclosed] {
diff --git a/apps/insights/src/components/Publishers/index.tsx b/apps/insights/src/components/Publishers/index.tsx
index 33bacafbe..8d229542a 100644
--- a/apps/insights/src/components/Publishers/index.tsx
+++ b/apps/insights/src/components/Publishers/index.tsx
@@ -36,7 +36,7 @@ export const Publishers = async () => {
Publishers
-
+
{
-
- {oisStats.totalStaked}
-
+
/{" "}
-
- {BigInt(oisStats.maxPoolSize ?? 0)}
-
+
@@ -134,7 +136,7 @@ export const Publishers = async () => {
stat={
<>
- {oisStats.totalStaked}
+
>
}
/>
@@ -144,15 +146,13 @@ export const Publishers = async () => {
stat={
<>
-
- {oisStats.rewardsDistributed}
-
+
>
}
/>
-
+
{
({ key, rank, numSymbols, medianScore }) => ({
id: key,
nameAsString: lookupPublisher(key)?.name,
- name: {key},
+ name: ,
ranking: {rank},
activeFeeds: numSymbols,
inactiveFeeds: totalFeeds - numSymbols,
@@ -195,8 +195,8 @@ const Ranking = ({ className, ...props }: ComponentProps<"span">) => (
);
-const PublisherName = ({ children }: { children: string }) => {
- const knownPublisher = lookupPublisher(children);
+const PublisherName = ({ publisherKey }: { publisherKey: string }) => {
+ const knownPublisher = lookupPublisher(publisherKey);
const Icon = knownPublisher?.icon.color ?? UndisclosedIcon;
const name = knownPublisher?.name ?? "Undisclosed";
return (
@@ -208,13 +208,23 @@ const PublisherName = ({ children }: { children: string }) => {
{knownPublisher ? (
{name}
-
- {`${children.slice(0, 4)}...${children.slice(-4)}`}
+
+ {`${publisherKey.slice(0, 4)}...${publisherKey.slice(-4)}`}
) : (
-
- {`${children.slice(0, 4)}...${children.slice(-4)}`}
+
+ {`${publisherKey.slice(0, 4)}...${publisherKey.slice(-4)}`}
)}
diff --git a/apps/insights/src/components/Publishers/publishers-card.tsx b/apps/insights/src/components/Publishers/publishers-card.tsx
index cff59b8c5..158d9fb35 100644
--- a/apps/insights/src/components/Publishers/publishers-card.tsx
+++ b/apps/insights/src/components/Publishers/publishers-card.tsx
@@ -128,7 +128,7 @@ const ResolvedPublishersCard = ({ publishers, ...props }: Props) => {
href: "#",
data: {
...data,
- medianScore:
{medianScore},
+ medianScore:
,
},
})),
[paginatedPublishers],
@@ -283,14 +283,15 @@ const PublishersCardContents = ({
);
type PublisherScoreProps = {
- children: number;
+ score: number;
};
-const PublisherScore = ({ children }: PublisherScoreProps) => (
+const PublisherScore = ({ score }: PublisherScoreProps) => (
{({ percentage }) => (
(
className={styles.fill}
style={{ width: `${(50 + percentage / 2).toString()}%` }}
>
- {children.toFixed(2)}
+ {score.toFixed(2)}
)}
diff --git a/apps/insights/src/components/Root/header.tsx b/apps/insights/src/components/Root/header.tsx
index 25124c41a..6004fa795 100644
--- a/apps/insights/src/components/Root/header.tsx
+++ b/apps/insights/src/components/Root/header.tsx
@@ -1,5 +1,4 @@
import { Lifebuoy } from "@phosphor-icons/react/dist/ssr/Lifebuoy";
-import { AppTabs } from "@pythnetwork/component-library/AppTabs";
import { Button, ButtonLink } from "@pythnetwork/component-library/Button";
import { Link } from "@pythnetwork/component-library/Link";
import clsx from "clsx";
@@ -8,6 +7,7 @@ import type { ComponentProps } from "react";
import styles from "./header.module.scss";
import Logo from "./logo.svg";
import { SearchButton } from "./search-button";
+import { MainNavTabs } from "./tabs";
import { ThemeSwitch } from "./theme-switch";
export const Header = ({ className, ...props }: ComponentProps<"header">) => (
@@ -21,17 +21,7 @@ export const Header = ({ className, ...props }: ComponentProps<"header">) => (
+ {typeof children === "function" ? children(state) : children}
+
)}
diff --git a/packages/component-library/src/Link/index.module.scss b/packages/component-library/src/Link/index.module.scss
index 608fb795d..09286913f 100644
--- a/packages/component-library/src/Link/index.module.scss
+++ b/packages/component-library/src/Link/index.module.scss
@@ -27,4 +27,12 @@
cursor: not-allowed;
color: theme.color("button", "disabled", "foreground");
}
+
+ &[data-invert] {
+ text-decoration: none;
+
+ &[data-hovered] {
+ text-decoration: underline;
+ }
+ }
}
diff --git a/packages/component-library/src/Link/index.stories.tsx b/packages/component-library/src/Link/index.stories.tsx
index f58cd0ea5..50e57874b 100644
--- a/packages/component-library/src/Link/index.stories.tsx
+++ b/packages/component-library/src/Link/index.stories.tsx
@@ -29,6 +29,12 @@ const meta = {
category: "State",
},
},
+ invert: {
+ control: "boolean",
+ table: {
+ category: "Link",
+ },
+ },
},
} satisfies Meta