diff --git a/examples/storybook/src/stories/design-system/Scorecard.stories.tsx b/examples/storybook/src/stories/design-system/Scorecard.stories.tsx new file mode 100644 index 00000000..c7ed1130 --- /dev/null +++ b/examples/storybook/src/stories/design-system/Scorecard.stories.tsx @@ -0,0 +1,82 @@ +/** + * Scorecard — KPI card showing a single metric with optional trend indicator. + */ +import React from 'react' +import type { Meta, StoryObj } from '@storybook/react' +import { Scorecard, XStack, YStack } from '@goodwidget/ui' +import type { ScorecardProps } from '@goodwidget/ui' +import { withDefaultPreset } from '../helpers/withDefaultPreset' + +/** The 5 mock-data rows from #139, reused to render both the bare and card variants. */ +const MOCK_ROWS: Array<{ slug: string; props: Omit }> = [ + { slug: 'total-spent', props: { label: 'Total G$ Spent', value: 1900, prefix: 'G$', format: 'compact' } }, + { slug: 'ai-credits', props: { label: 'AI Credits Used', value: 284.5, prefix: '$', format: 'decimal', decimals: 2 } }, + { slug: 'active-days', props: { label: 'Active Days', value: 28, format: 'none' } }, + { + slug: 'unique-wallets', + props: { label: 'Unique Wallets', value: 47, trend: { value: 15.3, direction: 'up' }, trendLabel: 'vs last 7d' }, + }, + { slug: 'daily-flow-rate', props: { label: 'Daily Flow Rate', value: 2450000, prefix: 'G$', suffix: '/day', format: 'compact' } }, +] + +const meta: Meta = { + title: 'Design System/Primitives/Scorecard', + component: Scorecard, + tags: ['autodocs', 'showcase'], + parameters: { layout: 'padded' }, + decorators: [withDefaultPreset], + argTypes: { + value: { control: 'number', description: 'The metric value to display' }, + label: { control: 'text', description: 'What the metric represents' }, + prefix: { control: 'text', description: 'Unit before the value' }, + suffix: { control: 'text', description: 'Unit after the value' }, + format: { + control: 'select', + options: ['compact', 'decimal', 'none'], + description: 'Number formatting mode', + }, + decimals: { control: 'number', description: 'Decimal precision' }, + variant: { + control: 'select', + options: ['bare', 'card'], + description: 'Chrome-less vs. card-wrapped face', + }, + size: { + control: 'select', + options: ['sm', 'md', 'lg'], + description: 'Typography size preset', + }, + }, +} +export default meta +type Story = StoryObj + +/** All 5 mock-data rows from #139, each rendered in both the bare and card variant. */ +export const Default: Story = { + render: () => ( + + + {MOCK_ROWS.map(({ slug, props }) => ( + + ))} + + + {MOCK_ROWS.map(({ slug, props }) => ( + + ))} + + + ), +} + +/** Controllable instance — edit args in the Controls panel. */ +export const Controllable: Story = { + args: { + label: 'Total G$ Spent', + value: 1900, + prefix: 'G$', + format: 'compact', + variant: 'card', + size: 'md', + }, +} diff --git a/packages/ui/package.json b/packages/ui/package.json index 3a6982dd..86a135c5 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -21,6 +21,7 @@ "peerDependencies": { "react": ">=18.0.0", "react-native": ">=0.76.0", + "react-native-svg": ">=15.0.0", "@react-native-clipboard/clipboard": ">=1.14.0" }, "peerDependenciesMeta": { @@ -42,6 +43,7 @@ "@types/react": "^18.3.0", "react": "^18.3.0", "react-native": "0.76.9", + "react-native-svg": "15.15.5", "react-native-web": "^0.19.13", "tsup": "^8.4.0", "typescript": "^5.7.0" diff --git a/packages/ui/src/components/Scorecard.tsx b/packages/ui/src/components/Scorecard.tsx new file mode 100644 index 00000000..9185fa97 --- /dev/null +++ b/packages/ui/src/components/Scorecard.tsx @@ -0,0 +1,329 @@ +/** + * Scorecard — reusable KPI card: a single metric value with a label and an + * optional trend indicator. First of 5 planned analytics chart components + * (packages/ui hosts all of them, per #139/#141). + * + * Structural pattern follows FundingDistributionChart (governance-widget): + * @goodwidget/ui primitives + useTheme() for color, react-native-svg for the + * one graphical element (the trend arrow), so it renders identically on + * React web, React Native, and Web Components. + */ +import React from 'react' +import Svg, { Path } from 'react-native-svg' +import { Text as TamaguiText, useTheme, XStack, YStack } from 'tamagui' +import { createComponent } from '../createComponent' +import { Card } from './Card' +import { formatMetricValue } from '../utils/formatMetricValue' +import type { MetricFormat } from '../utils/formatMetricValue' + +export type ScorecardVariant = 'bare' | 'card' +export type ScorecardSize = 'sm' | 'md' | 'lg' + +export interface ScorecardTrend { + value: number + direction: 'up' | 'down' | 'neutral' +} + +export interface ScorecardProps { + value: number + label: string + prefix?: string + suffix?: string + format?: MetricFormat + decimals?: number + trend?: ScorecardTrend + trendLabel?: string + variant?: ScorecardVariant + size?: ScorecardSize + testID?: string +} + +/** + * Golden-ratio modular type scale: every size step is the base value + * multiplied or divided by GOLDEN_RATIO, so the whole scale can be re-tuned + * later by adjusting these two constants instead of per-step pixel values. + */ +const SCORECARD_BASE_SIZE_PX = 24 +const GOLDEN_RATIO = 1.618 +const MIN_FONT_SIZE_PX = 12 + +const clampFontSize = (px: number): number => Math.max(px, MIN_FONT_SIZE_PX) + +const VALUE_SIZE_PX: Record = { + lg: clampFontSize(SCORECARD_BASE_SIZE_PX * GOLDEN_RATIO), + md: clampFontSize(SCORECARD_BASE_SIZE_PX), + sm: clampFontSize(SCORECARD_BASE_SIZE_PX / GOLDEN_RATIO), +} + +/** Label and trend text share the row below the value, one ratio step down. */ +const SECONDARY_SIZE_PX: Record = { + lg: clampFontSize(VALUE_SIZE_PX.lg / GOLDEN_RATIO), + md: clampFontSize(VALUE_SIZE_PX.md / GOLDEN_RATIO), + sm: clampFontSize(VALUE_SIZE_PX.sm / GOLDEN_RATIO), +} + +/** + * Vertical rhythm derived from the same base/ratio as the type scale, so + * spacing and typography stay on one proportional system instead of mixing + * in unrelated design tokens. + */ +const LABEL_TO_VALUE_GAP_PX = SCORECARD_BASE_SIZE_PX / GOLDEN_RATIO ** 2 +const VALUE_TO_TREND_GAP_PX = SCORECARD_BASE_SIZE_PX / GOLDEN_RATIO +const CARD_PADDING_PX = SCORECARD_BASE_SIZE_PX + +/** Semi-transparent white applied over the card background to lift it off the canvas by lightness rather than a border. */ +const CARD_ELEVATION_OVERLAY_COLOR = 'rgba(255,255,255,0.045)' +/** Simulates a light source hitting the card's top edge, replacing a hard border. */ +const CARD_TOP_HIGHLIGHT_COLOR = 'rgba(255,255,255,0.06)' + +const TREND_DIRECTION_COLOR_TOKEN: Record = { + up: '$success', + down: '$error', + neutral: '$colorDim', +} + +/** + * Unwraps a Tamagui theme token to its raw color string. react-native-svg's + * fill/stroke props aren't part of Tamagui's styling system, so they need + * the resolved value rather than a "$token" reference. + * + * Falls back to the theme's base `$color` token if the requested token is + * missing, so a bad token renders in a visible (if wrong) color instead of + * silently disappearing as black-on-web / transparent-on-native. + */ +function resolveThemeColor(theme: ReturnType, token: string): string { + const themeRecord = theme as unknown as Record + const key = token.replace('$', '') + const themeValue = themeRecord[key] + const resolved = + themeValue && typeof themeValue === 'object' && 'val' in themeValue + ? String(themeValue.val) + : typeof themeValue === 'string' + ? themeValue + : undefined + + if (resolved) { + return resolved + } + + console.warn(`Scorecard: theme token "${token}" not found, falling back to "$color"`) + + const fallback = themeRecord.color + return fallback && typeof fallback === 'object' && 'val' in fallback ? String(fallback.val) : '#000000' +} + +const ScorecardFrame = createComponent(YStack, { + name: 'Scorecard', + alignItems: 'center', + justifyContent: 'center', +}) + +const ScorecardLabelText = createComponent(TamaguiText, { + name: 'ScorecardLabelText', + fontFamily: '$body', + color: '$placeholderColor', + textAlign: 'center', + + variants: { + size: { + sm: { fontSize: SECONDARY_SIZE_PX.sm }, + md: { fontSize: SECONDARY_SIZE_PX.md }, + lg: { fontSize: SECONDARY_SIZE_PX.lg }, + }, + } as const, + + defaultVariants: { size: 'md' }, +}) + +const ScorecardValueRow = createComponent(XStack, { + name: 'ScorecardValueRow', + alignItems: 'baseline', + gap: '$1', + marginTop: LABEL_TO_VALUE_GAP_PX, +}) + +const ScorecardValueText = createComponent(TamaguiText, { + name: 'ScorecardValueText', + fontFamily: '$body', + fontWeight: '700', + // Theme text color, not $primary — $primary reads as an interactive/link + // hue, and the value is a headline, not a call to action. + color: '$color', + + variants: { + size: { + sm: { fontSize: VALUE_SIZE_PX.sm }, + md: { fontSize: VALUE_SIZE_PX.md }, + lg: { fontSize: VALUE_SIZE_PX.lg }, + }, + } as const, + + defaultVariants: { size: 'md' }, +}) + +/** + * Prefix/suffix (e.g. "G$", "/day") — same font size as the value since it's + * still part of the value row, but lighter weight and dimmer color so it + * stays subordinate to the value instead of competing with it. + */ +const ScorecardAffixText = createComponent(TamaguiText, { + name: 'ScorecardAffixText', + fontFamily: '$body', + fontWeight: '400', + color: '$placeholderColor', + + variants: { + size: { + sm: { fontSize: VALUE_SIZE_PX.sm }, + md: { fontSize: VALUE_SIZE_PX.md }, + lg: { fontSize: VALUE_SIZE_PX.lg }, + }, + } as const, + + defaultVariants: { size: 'md' }, +}) + +const ScorecardTrendRow = createComponent(XStack, { + name: 'ScorecardTrendRow', + alignItems: 'center', + gap: '$1', + marginTop: VALUE_TO_TREND_GAP_PX, +}) + +const ScorecardTrendText = createComponent(TamaguiText, { + name: 'ScorecardTrendText', + fontFamily: '$body', + fontWeight: '500', + + variants: { + size: { + sm: { fontSize: SECONDARY_SIZE_PX.sm }, + md: { fontSize: SECONDARY_SIZE_PX.md }, + lg: { fontSize: SECONDARY_SIZE_PX.lg }, + }, + } as const, + + defaultVariants: { size: 'md' }, +}) + +/** + * Up/down/neutral arrow glyph, drawn with react-native-svg for cross-platform + * rendering. Marked decorative (accessible={false} on native, aria-hidden on + * web) since the adjacent trend text already conveys the direction in words. + */ +function TrendGlyph({ direction, color, size }: { direction: ScorecardTrend['direction']; color: string; size: number }) { + const path = + direction === 'up' + ? 'M6 2 L10.5 9 L1.5 9 Z' + : direction === 'down' + ? 'M6 10 L10.5 3 L1.5 3 Z' + : 'M2 6 H10' + + if (direction === 'neutral') { + return ( + + + + ) + } + + return ( + + + + ) +} + +/** + * Elevation-by-lightness overlay for the card variant: an absolutely + * positioned semi-transparent white layer over the canvas-colored card, + * standing in for a shadow/border so depth reads from tone, not an outline. + * Sits as a sibling behind ScorecardContent inside a position:relative Card. + */ +const ScorecardCardOverlay = createComponent(YStack, { + name: 'ScorecardCardOverlay', + position: 'absolute', + top: 0, + left: 0, + right: 0, + bottom: 0, + backgroundColor: CARD_ELEVATION_OVERLAY_COLOR, +}) + +function formatTrendPercentage(trendValue: number, direction: ScorecardTrend['direction']): string { + const magnitude = Math.abs(trendValue).toFixed(1) + if (direction === 'up') return `+${magnitude}%` + if (direction === 'down') return `-${magnitude}%` + return `${magnitude}%` +} + +function ScorecardContent({ + value, + label, + prefix, + suffix, + format = 'compact', + decimals, + trend, + trendLabel, + size = 'md', + testID, +}: Omit) { + const theme = useTheme() + const formattedValue = formatMetricValue(value, format, decimals) + + return ( + // testID (React Native) and data-testid (web/DOM) both set so the same + // identifier works with either platform's test tooling. + + {label} + + {prefix ? {prefix} : null} + {formattedValue} + {suffix ? {suffix} : null} + + {trend ? ( + + + + {formatTrendPercentage(trend.value, trend.direction)} + {trendLabel ? ` ${trendLabel}` : ''} + + + ) : null} + + ) +} + +export function Scorecard({ variant = 'bare', ...contentProps }: ScorecardProps) { + if (variant === 'card') { + return ( + // Overrides scoped to this call site only — Card.ts itself stays + // untouched since it's shared by ~26 other widget-package consumers. + // position:relative + overflow:hidden host the absolutely positioned + // elevation overlay; justifyContent:center keeps content centered + // whether or not a trend row is present, so cards with/without a + // trend row still align evenly in a row layout. + + + + + ) + } + + return +} diff --git a/packages/ui/src/index.ts b/packages/ui/src/index.ts index faa698e9..662861f0 100644 --- a/packages/ui/src/index.ts +++ b/packages/ui/src/index.ts @@ -95,6 +95,12 @@ export { } from './components/Dialog' export type { DialogConfig, DialogStatus } from './components/Dialog' +// Analytics +export { Scorecard } from './components/Scorecard' +export type { ScorecardProps, ScorecardTrend, ScorecardVariant } from './components/Scorecard' +export { formatMetricValue } from './utils/formatMetricValue' +export type { MetricFormat } from './utils/formatMetricValue' + // Web3 export { AddressDisplay } from './components-test/AddressDisplay' export { TokenAmount } from './components/TokenAmount' diff --git a/packages/ui/src/utils/formatMetricValue.ts b/packages/ui/src/utils/formatMetricValue.ts new file mode 100644 index 00000000..9e9ea5c1 --- /dev/null +++ b/packages/ui/src/utils/formatMetricValue.ts @@ -0,0 +1,84 @@ +/** + * formatMetricValue — shared numeric formatter for analytics chart components + * (Scorecard is the first of 5 planned; all need the same compact K/M/B/T rules). + */ + +export type MetricFormat = 'compact' | 'decimal' | 'none' + +/** Non-finite values (NaN, Infinity) have no sensible numeric rendering. */ +const NON_FINITE_FALLBACK = '--' + +/** Ordered largest-first so the first matching threshold wins. */ +const COMPACT_THRESHOLDS = [ + { threshold: 1_000_000_000_000, suffix: 'T' }, + { threshold: 1_000_000_000, suffix: 'B' }, + { threshold: 1_000_000, suffix: 'M' }, + { threshold: 1_000, suffix: 'K' }, +] as const + +function assertNonNegativeInteger(decimals: number): void { + if (!Number.isInteger(decimals) || decimals < 0) { + throw new Error(`formatMetricValue: "decimals" must be a non-negative integer, received ${decimals}`) + } +} + +function formatCompact(value: number, decimals: number): string { + const absValue = Math.abs(value) + let thresholdIndex = COMPACT_THRESHOLDS.findIndex(({ threshold }) => absValue >= threshold) + + if (thresholdIndex === -1) { + // Below the smallest compact threshold: whole-number metrics (wallet + // counts, day counts, etc.) render without decimal places regardless of + // the requested precision — "47", not "47.0". + return Number.isInteger(value) ? String(value) : value.toFixed(decimals) + } + + // Rounding the scaled value can carry it up to the next unit (e.g. 999_950 → "1000.0K" + // instead of "1.0M"). Walk up to the next larger threshold (lower index) until the + // rounded value fits under 1000, or there's no larger unit left. + while (thresholdIndex > 0) { + const scaled = Number((value / COMPACT_THRESHOLDS[thresholdIndex].threshold).toFixed(decimals)) + + if (Math.abs(scaled) < 1000) { + break + } + + thresholdIndex -= 1 + } + + const { threshold, suffix } = COMPACT_THRESHOLDS[thresholdIndex] + + return `${(value / threshold).toFixed(decimals)}${suffix}` +} + +function formatDecimal(value: number, decimals: number): string { + // Intentionally hardcoded to en-US for v1; take a locale param once i18n is in scope. + return new Intl.NumberFormat('en-US', { + minimumFractionDigits: decimals, + maximumFractionDigits: decimals, + useGrouping: true, + }).format(value) +} + +/** + * Formats a raw metric value per the K/M/B/T "compact" scale, a full + * comma-grouped "decimal" form, or a "none" passthrough. + * + * `decimals` defaults to 1 for "compact" and 2 for "decimal" (per #139's spec) + * and must be a non-negative integer — invalid input is a developer error, + * not a runtime state, so it throws rather than silently clamping. + */ +export function formatMetricValue(value: number, format: MetricFormat = 'compact', decimals?: number): string { + if (!Number.isFinite(value)) { + return NON_FINITE_FALLBACK + } + + if (format === 'none') { + return String(value) + } + + const resolvedDecimals = decimals ?? (format === 'compact' ? 1 : 2) + assertNonNegativeInteger(resolvedDecimals) + + return format === 'compact' ? formatCompact(value, resolvedDecimals) : formatDecimal(value, resolvedDecimals) +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 33a08a66..cb6a4890 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -49,7 +49,7 @@ importers: version: link:../../packages/ui '@reown/appkit': specifier: ^1.8.22 - version: 1.8.22(@types/react@18.3.28)(@vercel/blob@2.4.0)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.6.0(react@18.3.1))(zod@4.1.11) + version: 1.8.22(@types/react@18.3.28)(@vercel/blob@2.4.0)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.6.0(react@18.3.1))(zod@3.25.76) '@tamagui/core': specifier: 1.121.0 version: 1.121.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -491,19 +491,19 @@ importers: version: 2.1.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@reown/appkit': specifier: ^1.8.22 - version: 1.8.22(@types/react@18.3.28)(@vercel/blob@2.4.0)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(zod@3.25.76) + version: 1.8.22(@types/react@18.3.28)(@vercel/blob@2.4.0)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(zod@4.1.11) '@reown/appkit-adapter-wagmi': specifier: ^1.8.22 - version: 1.8.22(isknxadknpp2cdfgti7v5vosu4) + version: 1.8.22(v6adbyiuvbtrgqm65ozlnb246m) '@tanstack/react-query': specifier: ^5.101.2 version: 5.101.2(react@18.3.1) viem: specifier: ^2.0.0 - version: 2.48.4(typescript@5.9.3)(zod@3.25.76) + version: 2.48.4(typescript@5.9.3)(zod@4.1.11) wagmi: specifier: ^3.7.1 - version: 3.7.1(@coinbase/wallet-sdk@4.3.6(@types/react@18.3.28)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(zod@3.25.76))(@safe-global/safe-apps-provider@0.18.6(typescript@5.9.3)(zod@3.25.76))(@safe-global/safe-apps-sdk@9.1.0(typescript@5.9.3)(zod@3.25.76))(@tanstack/query-core@5.101.2)(@tanstack/react-query@5.101.2(react@18.3.1))(@types/react@18.3.28)(react@18.3.1)(typescript@5.9.3)(viem@2.48.4(typescript@5.9.3)(zod@3.25.76)) + version: 3.7.1(@coinbase/wallet-sdk@4.3.6(@types/react@18.3.28)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(zod@4.1.11))(@safe-global/safe-apps-provider@0.18.6(typescript@5.9.3)(zod@4.1.11))(@safe-global/safe-apps-sdk@9.1.0(typescript@5.9.3)(zod@4.1.11))(@tanstack/query-core@5.101.2)(@tanstack/react-query@5.101.2(react@18.3.1))(@types/react@18.3.28)(react@18.3.1)(typescript@5.9.3)(viem@2.48.4(typescript@5.9.3)(zod@4.1.11)) devDependencies: '@types/react': specifier: ^18.3.0 @@ -739,6 +739,9 @@ importers: react-native: specifier: 0.76.9 version: 0.76.9(@babel/core@7.29.0)(@babel/preset-env@7.29.2(@babel/core@7.29.0))(@types/react@18.3.28)(react@18.3.1) + react-native-svg: + specifier: 15.15.5 + version: 15.15.5(react-native@0.76.9(@babel/core@7.29.0)(@babel/preset-env@7.29.2(@babel/core@7.29.0))(@types/react@18.3.28)(react@18.3.1))(react@18.3.1) react-native-web: specifier: ^0.19.13 version: 0.19.13(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -2048,7 +2051,7 @@ packages: '@expo/bunyan@4.0.1': resolution: {integrity: sha512-+Lla7nYSiHZirgK+U/uYzsLv/X+HaJienbD5AKX1UQZHYfWaP+9uuQluRB4GrEVWF0GZ7vEVp/jzaOT9k/SQlg==} - engines: {node: '>=0.10.0'} + engines: {'0': node >=0.10.0} '@expo/cli@0.22.28': resolution: {integrity: sha512-lvt72KNitGuixYD2l3SZmRKVu2G4zJpmg5V7WfUBNpmUU5oODBw/6qmiJ6kSLAlfDozscUk+BBGknBBzxUrwrA==} @@ -10728,7 +10731,31 @@ snapshots: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.28.5 - '@base-org/account@2.4.0(@types/react@18.3.28)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(zod@3.25.76)': + '@base-org/account@2.4.0(@types/react@18.3.28)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(zod@4.1.11)': + dependencies: + '@coinbase/cdp-sdk': 1.52.0(typescript@5.9.3) + '@noble/hashes': 1.4.0 + clsx: 1.2.1 + eventemitter3: 5.0.1 + idb-keyval: 6.2.1 + ox: 0.6.9(typescript@5.9.3)(zod@4.1.11) + preact: 10.24.2 + viem: 2.48.4(typescript@5.9.3)(zod@4.1.11) + zustand: 5.0.3(@types/react@18.3.28)(react@18.3.1)(use-sync-external-store@1.4.0(react@18.3.1)) + transitivePeerDependencies: + - '@types/react' + - bufferutil + - debug + - fastestsmallesttextencoderdecoder + - immer + - react + - typescript + - use-sync-external-store + - utf-8-validate + - zod + optional: true + + '@base-org/account@2.4.0(@types/react@18.3.28)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.6.0(react@18.3.1))(zod@3.25.76)': dependencies: '@coinbase/cdp-sdk': 1.52.0(typescript@5.9.3) '@noble/hashes': 1.4.0 @@ -10738,7 +10765,7 @@ snapshots: ox: 0.6.9(typescript@5.9.3)(zod@3.25.76) preact: 10.24.2 viem: 2.48.4(typescript@5.9.3)(zod@3.25.76) - zustand: 5.0.3(@types/react@18.3.28)(react@18.3.1)(use-sync-external-store@1.4.0(react@18.3.1)) + zustand: 5.0.3(@types/react@18.3.28)(react@18.3.1)(use-sync-external-store@1.6.0(react@18.3.1)) transitivePeerDependencies: - '@types/react' - bufferutil @@ -10802,7 +10829,28 @@ snapshots: - utf-8-validate optional: true - '@coinbase/wallet-sdk@4.3.6(@types/react@18.3.28)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(zod@3.25.76)': + '@coinbase/wallet-sdk@4.3.6(@types/react@18.3.28)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(zod@4.1.11)': + dependencies: + '@noble/hashes': 1.4.0 + clsx: 1.2.1 + eventemitter3: 5.0.1 + idb-keyval: 6.2.1 + ox: 0.6.9(typescript@5.9.3)(zod@4.1.11) + preact: 10.24.2 + viem: 2.48.4(typescript@5.9.3)(zod@4.1.11) + zustand: 5.0.3(@types/react@18.3.28)(react@18.3.1)(use-sync-external-store@1.4.0(react@18.3.1)) + transitivePeerDependencies: + - '@types/react' + - bufferutil + - immer + - react + - typescript + - use-sync-external-store + - utf-8-validate + - zod + optional: true + + '@coinbase/wallet-sdk@4.3.6(@types/react@18.3.28)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.6.0(react@18.3.1))(zod@3.25.76)': dependencies: '@noble/hashes': 1.4.0 clsx: 1.2.1 @@ -10811,7 +10859,7 @@ snapshots: ox: 0.6.9(typescript@5.9.3)(zod@3.25.76) preact: 10.24.2 viem: 2.48.4(typescript@5.9.3)(zod@3.25.76) - zustand: 5.0.3(@types/react@18.3.28)(react@18.3.1)(use-sync-external-store@1.4.0(react@18.3.1)) + zustand: 5.0.3(@types/react@18.3.28)(react@18.3.1)(use-sync-external-store@1.6.0(react@18.3.1)) transitivePeerDependencies: - '@types/react' - bufferutil @@ -12359,22 +12407,22 @@ snapshots: '@renovatebot/pep440@4.2.1': {} - '@reown/appkit-adapter-wagmi@1.8.22(isknxadknpp2cdfgti7v5vosu4)': + '@reown/appkit-adapter-wagmi@1.8.22(v6adbyiuvbtrgqm65ozlnb246m)': dependencies: - '@reown/appkit': 1.8.22(@types/react@18.3.28)(@vercel/blob@2.4.0)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(zod@3.25.76) - '@reown/appkit-common': 1.8.22(typescript@5.9.3)(zod@3.25.76) - '@reown/appkit-controllers': 1.8.22(@types/react@18.3.28)(@vercel/blob@2.4.0)(react@18.3.1)(typescript@5.9.3)(zod@3.25.76) + '@reown/appkit': 1.8.22(@types/react@18.3.28)(@vercel/blob@2.4.0)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(zod@4.1.11) + '@reown/appkit-common': 1.8.22(typescript@5.9.3)(zod@4.1.11) + '@reown/appkit-controllers': 1.8.22(@types/react@18.3.28)(@vercel/blob@2.4.0)(react@18.3.1)(typescript@5.9.3)(zod@4.1.11) '@reown/appkit-polyfills': 1.8.22 - '@reown/appkit-scaffold-ui': 1.8.22(@types/react@18.3.28)(@vercel/blob@2.4.0)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(valtio@2.1.7(@types/react@18.3.28)(react@18.3.1))(zod@3.25.76) - '@reown/appkit-utils': 1.8.22(@types/react@18.3.28)(@vercel/blob@2.4.0)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(valtio@2.1.7(@types/react@18.3.28)(react@18.3.1))(zod@3.25.76) + '@reown/appkit-scaffold-ui': 1.8.22(@types/react@18.3.28)(@vercel/blob@2.4.0)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(valtio@2.1.7(@types/react@18.3.28)(react@18.3.1))(zod@4.1.11) + '@reown/appkit-utils': 1.8.22(@types/react@18.3.28)(@vercel/blob@2.4.0)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(valtio@2.1.7(@types/react@18.3.28)(react@18.3.1))(zod@4.1.11) '@reown/appkit-wallet': 1.8.22(typescript@5.9.3) - '@wagmi/core': 3.6.1(@tanstack/query-core@5.101.2)(@types/react@18.3.28)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.48.4(typescript@5.9.3)(zod@3.25.76)) - '@walletconnect/universal-provider': 2.23.7(@vercel/blob@2.4.0)(typescript@5.9.3)(zod@3.25.76) + '@wagmi/core': 3.6.1(@tanstack/query-core@5.101.2)(@types/react@18.3.28)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.48.4(typescript@5.9.3)(zod@4.1.11)) + '@walletconnect/universal-provider': 2.23.7(@vercel/blob@2.4.0)(typescript@5.9.3)(zod@4.1.11) valtio: 2.1.7(@types/react@18.3.28)(react@18.3.1) - viem: 2.48.4(typescript@5.9.3)(zod@3.25.76) - wagmi: 3.7.1(@coinbase/wallet-sdk@4.3.6(@types/react@18.3.28)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(zod@3.25.76))(@safe-global/safe-apps-provider@0.18.6(typescript@5.9.3)(zod@3.25.76))(@safe-global/safe-apps-sdk@9.1.0(typescript@5.9.3)(zod@3.25.76))(@tanstack/query-core@5.101.2)(@tanstack/react-query@5.101.2(react@18.3.1))(@types/react@18.3.28)(react@18.3.1)(typescript@5.9.3)(viem@2.48.4(typescript@5.9.3)(zod@3.25.76)) + viem: 2.48.4(typescript@5.9.3)(zod@4.1.11) + wagmi: 3.7.1(@coinbase/wallet-sdk@4.3.6(@types/react@18.3.28)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(zod@4.1.11))(@safe-global/safe-apps-provider@0.18.6(typescript@5.9.3)(zod@4.1.11))(@safe-global/safe-apps-sdk@9.1.0(typescript@5.9.3)(zod@4.1.11))(@tanstack/query-core@5.101.2)(@tanstack/react-query@5.101.2(react@18.3.1))(@types/react@18.3.28)(react@18.3.1)(typescript@5.9.3)(viem@2.48.4(typescript@5.9.3)(zod@4.1.11)) optionalDependencies: - '@wagmi/connectors': 8.0.8(@coinbase/wallet-sdk@4.3.6(@types/react@18.3.28)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(zod@3.25.76))(@safe-global/safe-apps-provider@0.18.6(typescript@5.9.3)(zod@3.25.76))(@safe-global/safe-apps-sdk@9.1.0(typescript@5.9.3)(zod@3.25.76))(@wagmi/core@3.6.1(@tanstack/query-core@5.101.2)(@types/react@18.3.28)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.48.4(typescript@5.9.3)(zod@3.25.76)))(typescript@5.9.3)(viem@2.48.4(typescript@5.9.3)(zod@3.25.76)) + '@wagmi/connectors': 8.0.8(@coinbase/wallet-sdk@4.3.6(@types/react@18.3.28)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(zod@4.1.11))(@safe-global/safe-apps-provider@0.18.6(typescript@5.9.3)(zod@4.1.11))(@safe-global/safe-apps-sdk@9.1.0(typescript@5.9.3)(zod@4.1.11))(@wagmi/core@3.6.1(@tanstack/query-core@5.101.2)(@types/react@18.3.28)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.48.4(typescript@5.9.3)(zod@4.1.11)))(typescript@5.9.3)(viem@2.48.4(typescript@5.9.3)(zod@4.1.11)) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -12518,12 +12566,52 @@ snapshots: - utf-8-validate - zod - '@reown/appkit-pay@1.8.22(@types/react@18.3.28)(@vercel/blob@2.4.0)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(zod@3.25.76)': + '@reown/appkit-pay@1.8.22(@types/react@18.3.28)(@vercel/blob@2.4.0)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(zod@4.1.11)': + dependencies: + '@reown/appkit-common': 1.8.22(typescript@5.9.3)(zod@4.1.11) + '@reown/appkit-controllers': 1.8.22(@types/react@18.3.28)(@vercel/blob@2.4.0)(react@18.3.1)(typescript@5.9.3)(zod@4.1.11) + '@reown/appkit-ui': 1.8.22(@types/react@18.3.28)(@vercel/blob@2.4.0)(react@18.3.1)(typescript@5.9.3)(zod@4.1.11) + '@reown/appkit-utils': 1.8.22(@types/react@18.3.28)(@vercel/blob@2.4.0)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(valtio@2.1.7(@types/react@18.3.28)(react@18.3.1))(zod@4.1.11) + lit: 3.3.0 + valtio: 2.1.7(@types/react@18.3.28)(react@18.3.1) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@types/react' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - debug + - encoding + - fastestsmallesttextencoderdecoder + - immer + - ioredis + - react + - typescript + - uploadthing + - use-sync-external-store + - utf-8-validate + - zod + + '@reown/appkit-pay@1.8.22(@types/react@18.3.28)(@vercel/blob@2.4.0)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.6.0(react@18.3.1))(zod@3.25.76)': dependencies: '@reown/appkit-common': 1.8.22(typescript@5.9.3)(zod@3.25.76) '@reown/appkit-controllers': 1.8.22(@types/react@18.3.28)(@vercel/blob@2.4.0)(react@18.3.1)(typescript@5.9.3)(zod@3.25.76) '@reown/appkit-ui': 1.8.22(@types/react@18.3.28)(@vercel/blob@2.4.0)(react@18.3.1)(typescript@5.9.3)(zod@3.25.76) - '@reown/appkit-utils': 1.8.22(@types/react@18.3.28)(@vercel/blob@2.4.0)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(valtio@2.1.7(@types/react@18.3.28)(react@18.3.1))(zod@3.25.76) + '@reown/appkit-utils': 1.8.22(@types/react@18.3.28)(@vercel/blob@2.4.0)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.6.0(react@18.3.1))(valtio@2.1.7(@types/react@18.3.28)(react@18.3.1))(zod@3.25.76) lit: 3.3.0 valtio: 2.1.7(@types/react@18.3.28)(react@18.3.1) transitivePeerDependencies: @@ -12602,13 +12690,55 @@ snapshots: dependencies: buffer: 6.0.3 - '@reown/appkit-scaffold-ui@1.8.22(@types/react@18.3.28)(@vercel/blob@2.4.0)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(valtio@2.1.7(@types/react@18.3.28)(react@18.3.1))(zod@3.25.76)': + '@reown/appkit-scaffold-ui@1.8.22(@types/react@18.3.28)(@vercel/blob@2.4.0)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(valtio@2.1.7(@types/react@18.3.28)(react@18.3.1))(zod@4.1.11)': + dependencies: + '@reown/appkit-common': 1.8.22(typescript@5.9.3)(zod@4.1.11) + '@reown/appkit-controllers': 1.8.22(@types/react@18.3.28)(@vercel/blob@2.4.0)(react@18.3.1)(typescript@5.9.3)(zod@4.1.11) + '@reown/appkit-pay': 1.8.22(@types/react@18.3.28)(@vercel/blob@2.4.0)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(zod@4.1.11) + '@reown/appkit-ui': 1.8.22(@types/react@18.3.28)(@vercel/blob@2.4.0)(react@18.3.1)(typescript@5.9.3)(zod@4.1.11) + '@reown/appkit-utils': 1.8.22(@types/react@18.3.28)(@vercel/blob@2.4.0)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(valtio@2.1.7(@types/react@18.3.28)(react@18.3.1))(zod@4.1.11) + '@reown/appkit-wallet': 1.8.22(typescript@5.9.3) + lit: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@types/react' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - debug + - encoding + - fastestsmallesttextencoderdecoder + - immer + - ioredis + - react + - typescript + - uploadthing + - use-sync-external-store + - utf-8-validate + - valtio + - zod + + '@reown/appkit-scaffold-ui@1.8.22(@types/react@18.3.28)(@vercel/blob@2.4.0)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.6.0(react@18.3.1))(valtio@2.1.7(@types/react@18.3.28)(react@18.3.1))(zod@3.25.76)': dependencies: '@reown/appkit-common': 1.8.22(typescript@5.9.3)(zod@3.25.76) '@reown/appkit-controllers': 1.8.22(@types/react@18.3.28)(@vercel/blob@2.4.0)(react@18.3.1)(typescript@5.9.3)(zod@3.25.76) - '@reown/appkit-pay': 1.8.22(@types/react@18.3.28)(@vercel/blob@2.4.0)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(zod@3.25.76) + '@reown/appkit-pay': 1.8.22(@types/react@18.3.28)(@vercel/blob@2.4.0)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.6.0(react@18.3.1))(zod@3.25.76) '@reown/appkit-ui': 1.8.22(@types/react@18.3.28)(@vercel/blob@2.4.0)(react@18.3.1)(typescript@5.9.3)(zod@3.25.76) - '@reown/appkit-utils': 1.8.22(@types/react@18.3.28)(@vercel/blob@2.4.0)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(valtio@2.1.7(@types/react@18.3.28)(react@18.3.1))(zod@3.25.76) + '@reown/appkit-utils': 1.8.22(@types/react@18.3.28)(@vercel/blob@2.4.0)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.6.0(react@18.3.1))(valtio@2.1.7(@types/react@18.3.28)(react@18.3.1))(zod@3.25.76) '@reown/appkit-wallet': 1.8.22(typescript@5.9.3) lit: 3.3.0 transitivePeerDependencies: @@ -12758,7 +12888,55 @@ snapshots: - utf-8-validate - zod - '@reown/appkit-utils@1.8.22(@types/react@18.3.28)(@vercel/blob@2.4.0)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(valtio@2.1.7(@types/react@18.3.28)(react@18.3.1))(zod@3.25.76)': + '@reown/appkit-utils@1.8.22(@types/react@18.3.28)(@vercel/blob@2.4.0)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(valtio@2.1.7(@types/react@18.3.28)(react@18.3.1))(zod@4.1.11)': + dependencies: + '@reown/appkit-common': 1.8.22(typescript@5.9.3)(zod@4.1.11) + '@reown/appkit-controllers': 1.8.22(@types/react@18.3.28)(@vercel/blob@2.4.0)(react@18.3.1)(typescript@5.9.3)(zod@4.1.11) + '@reown/appkit-polyfills': 1.8.22 + '@reown/appkit-wallet': 1.8.22(typescript@5.9.3) + '@wallet-standard/wallet': 1.1.0 + '@walletconnect/logger': 3.0.2 + '@walletconnect/universal-provider': 2.23.7(@vercel/blob@2.4.0)(typescript@5.9.3)(zod@4.1.11) + valtio: 2.1.7(@types/react@18.3.28)(react@18.3.1) + viem: 2.48.4(typescript@5.9.3)(zod@4.1.11) + optionalDependencies: + '@base-org/account': 2.4.0(@types/react@18.3.28)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(zod@4.1.11) + '@coinbase/wallet-sdk': 4.3.6(@types/react@18.3.28)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(zod@4.1.11) + '@safe-global/safe-apps-provider': 0.18.6(typescript@5.9.3)(zod@4.1.11) + '@safe-global/safe-apps-sdk': 9.1.0(typescript@5.9.3)(zod@4.1.11) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@types/react' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - debug + - encoding + - fastestsmallesttextencoderdecoder + - immer + - ioredis + - react + - typescript + - uploadthing + - use-sync-external-store + - utf-8-validate + - zod + + '@reown/appkit-utils@1.8.22(@types/react@18.3.28)(@vercel/blob@2.4.0)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.6.0(react@18.3.1))(valtio@2.1.7(@types/react@18.3.28)(react@18.3.1))(zod@3.25.76)': dependencies: '@reown/appkit-common': 1.8.22(typescript@5.9.3)(zod@3.25.76) '@reown/appkit-controllers': 1.8.22(@types/react@18.3.28)(@vercel/blob@2.4.0)(react@18.3.1)(typescript@5.9.3)(zod@3.25.76) @@ -12770,8 +12948,8 @@ snapshots: valtio: 2.1.7(@types/react@18.3.28)(react@18.3.1) viem: 2.48.4(typescript@5.9.3)(zod@3.25.76) optionalDependencies: - '@base-org/account': 2.4.0(@types/react@18.3.28)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(zod@3.25.76) - '@coinbase/wallet-sdk': 4.3.6(@types/react@18.3.28)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(zod@3.25.76) + '@base-org/account': 2.4.0(@types/react@18.3.28)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.6.0(react@18.3.1))(zod@3.25.76) + '@coinbase/wallet-sdk': 4.3.6(@types/react@18.3.28)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.6.0(react@18.3.1))(zod@3.25.76) '@safe-global/safe-apps-provider': 0.18.6(typescript@5.9.3)(zod@3.25.76) '@safe-global/safe-apps-sdk': 9.1.0(typescript@5.9.3)(zod@3.25.76) transitivePeerDependencies: @@ -12865,15 +13043,64 @@ snapshots: - typescript - utf-8-validate - '@reown/appkit@1.8.22(@types/react@18.3.28)(@vercel/blob@2.4.0)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(zod@3.25.76)': + '@reown/appkit@1.8.22(@types/react@18.3.28)(@vercel/blob@2.4.0)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(zod@4.1.11)': + dependencies: + '@reown/appkit-common': 1.8.22(typescript@5.9.3)(zod@4.1.11) + '@reown/appkit-controllers': 1.8.22(@types/react@18.3.28)(@vercel/blob@2.4.0)(react@18.3.1)(typescript@5.9.3)(zod@4.1.11) + '@reown/appkit-pay': 1.8.22(@types/react@18.3.28)(@vercel/blob@2.4.0)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(zod@4.1.11) + '@reown/appkit-polyfills': 1.8.22 + '@reown/appkit-scaffold-ui': 1.8.22(@types/react@18.3.28)(@vercel/blob@2.4.0)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(valtio@2.1.7(@types/react@18.3.28)(react@18.3.1))(zod@4.1.11) + '@reown/appkit-ui': 1.8.22(@types/react@18.3.28)(@vercel/blob@2.4.0)(react@18.3.1)(typescript@5.9.3)(zod@4.1.11) + '@reown/appkit-utils': 1.8.22(@types/react@18.3.28)(@vercel/blob@2.4.0)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(valtio@2.1.7(@types/react@18.3.28)(react@18.3.1))(zod@4.1.11) + '@reown/appkit-wallet': 1.8.22(typescript@5.9.3) + '@walletconnect/universal-provider': 2.23.7(@vercel/blob@2.4.0)(typescript@5.9.3)(zod@4.1.11) + bs58: 6.0.0 + semver: 7.7.2 + valtio: 2.1.7(@types/react@18.3.28)(react@18.3.1) + viem: 2.48.4(typescript@5.9.3)(zod@4.1.11) + optionalDependencies: + '@lit/react': 1.0.8(@types/react@18.3.28) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@types/react' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - debug + - encoding + - fastestsmallesttextencoderdecoder + - immer + - ioredis + - react + - typescript + - uploadthing + - use-sync-external-store + - utf-8-validate + - zod + + '@reown/appkit@1.8.22(@types/react@18.3.28)(@vercel/blob@2.4.0)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.6.0(react@18.3.1))(zod@3.25.76)': dependencies: '@reown/appkit-common': 1.8.22(typescript@5.9.3)(zod@3.25.76) '@reown/appkit-controllers': 1.8.22(@types/react@18.3.28)(@vercel/blob@2.4.0)(react@18.3.1)(typescript@5.9.3)(zod@3.25.76) - '@reown/appkit-pay': 1.8.22(@types/react@18.3.28)(@vercel/blob@2.4.0)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(zod@3.25.76) + '@reown/appkit-pay': 1.8.22(@types/react@18.3.28)(@vercel/blob@2.4.0)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.6.0(react@18.3.1))(zod@3.25.76) '@reown/appkit-polyfills': 1.8.22 - '@reown/appkit-scaffold-ui': 1.8.22(@types/react@18.3.28)(@vercel/blob@2.4.0)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(valtio@2.1.7(@types/react@18.3.28)(react@18.3.1))(zod@3.25.76) + '@reown/appkit-scaffold-ui': 1.8.22(@types/react@18.3.28)(@vercel/blob@2.4.0)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.6.0(react@18.3.1))(valtio@2.1.7(@types/react@18.3.28)(react@18.3.1))(zod@3.25.76) '@reown/appkit-ui': 1.8.22(@types/react@18.3.28)(@vercel/blob@2.4.0)(react@18.3.1)(typescript@5.9.3)(zod@3.25.76) - '@reown/appkit-utils': 1.8.22(@types/react@18.3.28)(@vercel/blob@2.4.0)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(valtio@2.1.7(@types/react@18.3.28)(react@18.3.1))(zod@3.25.76) + '@reown/appkit-utils': 1.8.22(@types/react@18.3.28)(@vercel/blob@2.4.0)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.6.0(react@18.3.1))(valtio@2.1.7(@types/react@18.3.28)(react@18.3.1))(zod@3.25.76) '@reown/appkit-wallet': 1.8.22(typescript@5.9.3) '@walletconnect/universal-provider': 2.23.7(@vercel/blob@2.4.0)(typescript@5.9.3)(zod@3.25.76) bs58: 6.0.0 @@ -15993,14 +16220,14 @@ snapshots: loupe: 3.2.1 tinyrainbow: 1.2.0 - '@wagmi/connectors@8.0.22(@coinbase/wallet-sdk@4.3.6(@types/react@18.3.28)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(zod@3.25.76))(@safe-global/safe-apps-provider@0.18.6(typescript@5.9.3)(zod@3.25.76))(@safe-global/safe-apps-sdk@9.1.0(typescript@5.9.3)(zod@3.25.76))(@wagmi/core@3.6.1(@tanstack/query-core@5.101.2)(@types/react@18.3.28)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.48.4(typescript@5.9.3)(zod@3.25.76)))(typescript@5.9.3)(viem@2.48.4(typescript@5.9.3)(zod@3.25.76))': + '@wagmi/connectors@8.0.22(@coinbase/wallet-sdk@4.3.6(@types/react@18.3.28)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(zod@4.1.11))(@safe-global/safe-apps-provider@0.18.6(typescript@5.9.3)(zod@4.1.11))(@safe-global/safe-apps-sdk@9.1.0(typescript@5.9.3)(zod@4.1.11))(@wagmi/core@3.6.1(@tanstack/query-core@5.101.2)(@types/react@18.3.28)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.48.4(typescript@5.9.3)(zod@4.1.11)))(typescript@5.9.3)(viem@2.48.4(typescript@5.9.3)(zod@4.1.11))': dependencies: - '@wagmi/core': 3.6.1(@tanstack/query-core@5.101.2)(@types/react@18.3.28)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.48.4(typescript@5.9.3)(zod@3.25.76)) - viem: 2.48.4(typescript@5.9.3)(zod@3.25.76) + '@wagmi/core': 3.6.1(@tanstack/query-core@5.101.2)(@types/react@18.3.28)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.48.4(typescript@5.9.3)(zod@4.1.11)) + viem: 2.48.4(typescript@5.9.3)(zod@4.1.11) optionalDependencies: - '@coinbase/wallet-sdk': 4.3.6(@types/react@18.3.28)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(zod@3.25.76) - '@safe-global/safe-apps-provider': 0.18.6(typescript@5.9.3)(zod@3.25.76) - '@safe-global/safe-apps-sdk': 9.1.0(typescript@5.9.3)(zod@3.25.76) + '@coinbase/wallet-sdk': 4.3.6(@types/react@18.3.28)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(zod@4.1.11) + '@safe-global/safe-apps-provider': 0.18.6(typescript@5.9.3)(zod@4.1.11) + '@safe-global/safe-apps-sdk': 9.1.0(typescript@5.9.3)(zod@4.1.11) typescript: 5.9.3 '@wagmi/connectors@8.0.22(@coinbase/wallet-sdk@4.3.6(@types/react@18.3.28)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.6.0(react@18.3.1))(zod@4.1.11))(@safe-global/safe-apps-provider@0.18.6(typescript@5.9.3)(zod@4.1.11))(@safe-global/safe-apps-sdk@9.1.0(typescript@5.9.3)(zod@4.1.11))(@wagmi/core@3.6.1(@tanstack/query-core@5.101.2)(@types/react@18.3.28)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.48.4(typescript@5.9.3)(zod@4.1.11)))(typescript@5.9.3)(viem@2.48.4(typescript@5.9.3)(zod@4.1.11))': @@ -16013,32 +16240,17 @@ snapshots: '@safe-global/safe-apps-sdk': 9.1.0(typescript@5.9.3)(zod@4.1.11) typescript: 5.9.3 - '@wagmi/connectors@8.0.8(@coinbase/wallet-sdk@4.3.6(@types/react@18.3.28)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(zod@3.25.76))(@safe-global/safe-apps-provider@0.18.6(typescript@5.9.3)(zod@3.25.76))(@safe-global/safe-apps-sdk@9.1.0(typescript@5.9.3)(zod@3.25.76))(@wagmi/core@3.6.1(@tanstack/query-core@5.101.2)(@types/react@18.3.28)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.48.4(typescript@5.9.3)(zod@3.25.76)))(typescript@5.9.3)(viem@2.48.4(typescript@5.9.3)(zod@3.25.76))': + '@wagmi/connectors@8.0.8(@coinbase/wallet-sdk@4.3.6(@types/react@18.3.28)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(zod@4.1.11))(@safe-global/safe-apps-provider@0.18.6(typescript@5.9.3)(zod@4.1.11))(@safe-global/safe-apps-sdk@9.1.0(typescript@5.9.3)(zod@4.1.11))(@wagmi/core@3.6.1(@tanstack/query-core@5.101.2)(@types/react@18.3.28)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.48.4(typescript@5.9.3)(zod@4.1.11)))(typescript@5.9.3)(viem@2.48.4(typescript@5.9.3)(zod@4.1.11))': dependencies: - '@wagmi/core': 3.6.1(@tanstack/query-core@5.101.2)(@types/react@18.3.28)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.48.4(typescript@5.9.3)(zod@3.25.76)) - viem: 2.48.4(typescript@5.9.3)(zod@3.25.76) + '@wagmi/core': 3.6.1(@tanstack/query-core@5.101.2)(@types/react@18.3.28)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.48.4(typescript@5.9.3)(zod@4.1.11)) + viem: 2.48.4(typescript@5.9.3)(zod@4.1.11) optionalDependencies: - '@coinbase/wallet-sdk': 4.3.6(@types/react@18.3.28)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(zod@3.25.76) - '@safe-global/safe-apps-provider': 0.18.6(typescript@5.9.3)(zod@3.25.76) - '@safe-global/safe-apps-sdk': 9.1.0(typescript@5.9.3)(zod@3.25.76) + '@coinbase/wallet-sdk': 4.3.6(@types/react@18.3.28)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(zod@4.1.11) + '@safe-global/safe-apps-provider': 0.18.6(typescript@5.9.3)(zod@4.1.11) + '@safe-global/safe-apps-sdk': 9.1.0(typescript@5.9.3)(zod@4.1.11) typescript: 5.9.3 optional: true - '@wagmi/core@3.6.1(@tanstack/query-core@5.101.2)(@types/react@18.3.28)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.48.4(typescript@5.9.3)(zod@3.25.76))': - dependencies: - eventemitter3: 5.0.1 - mipd: 0.0.7(typescript@5.9.3) - viem: 2.48.4(typescript@5.9.3)(zod@3.25.76) - zustand: 5.0.0(@types/react@18.3.28)(react@18.3.1)(use-sync-external-store@1.4.0(react@18.3.1)) - optionalDependencies: - '@tanstack/query-core': 5.101.2 - typescript: 5.9.3 - transitivePeerDependencies: - - '@types/react' - - immer - - react - - use-sync-external-store - '@wagmi/core@3.6.1(@tanstack/query-core@5.101.2)(@types/react@18.3.28)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.48.4(typescript@5.9.3)(zod@4.1.11))': dependencies: eventemitter3: 5.0.1 @@ -21921,14 +22133,14 @@ snapshots: w-json@1.3.11: {} - wagmi@3.7.1(@coinbase/wallet-sdk@4.3.6(@types/react@18.3.28)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(zod@3.25.76))(@safe-global/safe-apps-provider@0.18.6(typescript@5.9.3)(zod@3.25.76))(@safe-global/safe-apps-sdk@9.1.0(typescript@5.9.3)(zod@3.25.76))(@tanstack/query-core@5.101.2)(@tanstack/react-query@5.101.2(react@18.3.1))(@types/react@18.3.28)(react@18.3.1)(typescript@5.9.3)(viem@2.48.4(typescript@5.9.3)(zod@3.25.76)): + wagmi@3.7.1(@coinbase/wallet-sdk@4.3.6(@types/react@18.3.28)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(zod@4.1.11))(@safe-global/safe-apps-provider@0.18.6(typescript@5.9.3)(zod@4.1.11))(@safe-global/safe-apps-sdk@9.1.0(typescript@5.9.3)(zod@4.1.11))(@tanstack/query-core@5.101.2)(@tanstack/react-query@5.101.2(react@18.3.1))(@types/react@18.3.28)(react@18.3.1)(typescript@5.9.3)(viem@2.48.4(typescript@5.9.3)(zod@4.1.11)): dependencies: '@tanstack/react-query': 5.101.2(react@18.3.1) - '@wagmi/connectors': 8.0.22(@coinbase/wallet-sdk@4.3.6(@types/react@18.3.28)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(zod@3.25.76))(@safe-global/safe-apps-provider@0.18.6(typescript@5.9.3)(zod@3.25.76))(@safe-global/safe-apps-sdk@9.1.0(typescript@5.9.3)(zod@3.25.76))(@wagmi/core@3.6.1(@tanstack/query-core@5.101.2)(@types/react@18.3.28)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.48.4(typescript@5.9.3)(zod@3.25.76)))(typescript@5.9.3)(viem@2.48.4(typescript@5.9.3)(zod@3.25.76)) - '@wagmi/core': 3.6.1(@tanstack/query-core@5.101.2)(@types/react@18.3.28)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.48.4(typescript@5.9.3)(zod@3.25.76)) + '@wagmi/connectors': 8.0.22(@coinbase/wallet-sdk@4.3.6(@types/react@18.3.28)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(zod@4.1.11))(@safe-global/safe-apps-provider@0.18.6(typescript@5.9.3)(zod@4.1.11))(@safe-global/safe-apps-sdk@9.1.0(typescript@5.9.3)(zod@4.1.11))(@wagmi/core@3.6.1(@tanstack/query-core@5.101.2)(@types/react@18.3.28)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.48.4(typescript@5.9.3)(zod@4.1.11)))(typescript@5.9.3)(viem@2.48.4(typescript@5.9.3)(zod@4.1.11)) + '@wagmi/core': 3.6.1(@tanstack/query-core@5.101.2)(@types/react@18.3.28)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.48.4(typescript@5.9.3)(zod@4.1.11)) react: 18.3.1 use-sync-external-store: 1.4.0(react@18.3.1) - viem: 2.48.4(typescript@5.9.3)(zod@3.25.76) + viem: 2.48.4(typescript@5.9.3)(zod@4.1.11) optionalDependencies: typescript: 5.9.3 transitivePeerDependencies: diff --git a/tests/design-system/smoke.spec.ts b/tests/design-system/smoke.spec.ts index f9297c25..a430f898 100644 --- a/tests/design-system/smoke.spec.ts +++ b/tests/design-system/smoke.spec.ts @@ -110,3 +110,22 @@ test('Stepper/Default story renders active-step hierarchy', async ({ page }) => await expect(frame.getByTestId('Stepper-default')).toBeVisible() await screenshotStory(page, 'tests/design-system/test-results/story-stepper-default.png') }) + +test('Scorecard/Default story renders all 5 mock-data rows in both variants', async ({ page }) => { + // Taller than the default viewport so both the bare and card rows fit + // without clipping — 10 cards across two rows need more vertical space + // than a single-row story. 1000 (rather than 900) accounts for the + // increased card padding/spacing from the golden-ratio spacing pass. + await page.setViewportSize({ width: 1280, height: 1000 }) + await gotoStory(page, 'design-system-primitives-scorecard--default') + const frame = getStoryFrame(page) + await expect(frame.getByTestId('Scorecard-default')).toBeVisible() + + const rowSlugs = ['total-spent', 'ai-credits', 'active-days', 'unique-wallets', 'daily-flow-rate'] + for (const slug of rowSlugs) { + await expect(frame.getByTestId(`Scorecard-${slug}-bare`)).toBeVisible() + await expect(frame.getByTestId(`Scorecard-${slug}-card`)).toBeVisible() + } + + await screenshotStory(page, 'tests/design-system/test-results/story-scorecard-default.png') +}) diff --git a/tests/design-system/test-results/story-scorecard-default.png b/tests/design-system/test-results/story-scorecard-default.png new file mode 100644 index 00000000..42b722d1 Binary files /dev/null and b/tests/design-system/test-results/story-scorecard-default.png differ