Skip to content
Open
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
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { cn, Icon, Text, Wrapper } from '@zerodev/react-ui'
import { LoadingCard } from '../LoadingCard'

/**
* The card that renders the deposit address in the SRA "Deposit funds" screen.
*
* Two visual states, each mapped 1:1 to a Figma node:
* - Loading (Figma 17634:104343, "Smart Funding" card): 16px radius, 20%
* white surface, centered loading icon + `loadingText`. Rendered when
* `address` is omitted.
* - Loading (Figma 17634:104343, "Smart Funding" card): delegates to
* `LoadingCard`, which is the shared spinner+text pill used elsewhere in
* the SRA flow (e.g., SmartFunding's "Watching for deposit" state).
* - Ready (Figma 17762:78875, address+QR row): 14px radius, 40% offWhite
* surface, left-aligned address text + a 52×52 white QR button on the
* right. Rendered when `address` is supplied.
Expand Down Expand Up @@ -35,23 +36,11 @@ export function AddressDisplay({
}: AddressDisplayProps) {
if (address === undefined) {
return (
<Wrapper
variant="ghost"
className={cn(
// Figma: rounded-2xl (16px), p-16, centered content, gap 8px, 20%
// white surface from Wrapper's ghost variant. Height pinned to
// 68px so it matches the ready variant.
'zd:relative zd:flex zd:h-[68px] zd:w-full zd:items-center zd:justify-center zd:gap-2 zd:overflow-hidden zd:rounded-2xl zd:px-4',
'zd:shadow-[inset_0_-4px_4px_0_rgba(255,255,255,0.1),inset_0_3px_4px_0_rgba(0,0,0,0.02)]',
className,
)}
<LoadingCard
text={loadingText}
className={className}
data-testid="address-display-loading"
>
<Icon name="lineLoading" className="zd:size-4 zd:text-greyScale/50" />
<Text className="zd:text-body1 zd:text-greyScale/50">
{loadingText}
</Text>
</Wrapper>
/>
)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import type { Meta, StoryObj } from '@storybook/react-vite'
import { LoadingCard } from './index'

const meta: Meta<typeof LoadingCard> = {
title: 'SmartRoutingAddress/LoadingCard',
component: LoadingCard,
parameters: { layout: 'centered' },
decorators: [
(Story) => (
<div style={{ width: 368 }}>
<Story />
</div>
),
],
}

export default meta
type Story = StoryObj<typeof meta>

/** Used inside `AddressDisplay`'s loading variant while the SRA server
* is generating the deposit address. */
export const GeneratingAddress: Story = {
args: {
text: 'Generating deposit address…',
},
}

/** Used inside `SmartFunding` while the app is watching for an incoming
* deposit at the generated address. */
export const WatchingForDeposit: Story = {
args: {
text: 'Watching for your deposit on Base…',
},
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/**
* @vitest-environment happy-dom
*/
import { cleanup, render, screen } from '@testing-library/react'
import { afterEach, describe, expect, it } from 'vitest'
import { LoadingCard } from './index'

afterEach(cleanup)

describe('LoadingCard', () => {
it('renders the status text', () => {
render(<LoadingCard text="Watching for your deposit on Base…" />)
expect(screen.getByText('Watching for your deposit on Base…')).toBeDefined()
})

it('renders the spinner icon', () => {
render(<LoadingCard text="Loading…" />)
expect(screen.getByTestId('loading-card-icon')).toBeDefined()
})

it('forwards extra HTML attributes (e.g., data-testid) to the root', () => {
render(<LoadingCard text="Loading…" data-testid="custom-root" />)
expect(screen.getByTestId('custom-root')).toBeDefined()
})

it('merges custom className with defaults', () => {
const { container } = render(
<LoadingCard text="Loading…" className="custom-class" />,
)
const root = container.firstChild as HTMLElement
expect(root.className).toContain('custom-class')
// Sanity: the default height class is still applied
expect(root.className).toContain('zd:h-[68px]')
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { cn, Icon, Text, Wrapper } from '@zerodev/react-ui'
import type { HTMLAttributes } from 'react'

export interface LoadingCardProps extends HTMLAttributes<HTMLDivElement> {
text: string
}

export function LoadingCard({ text, className, ...rest }: LoadingCardProps) {
return (
<Wrapper
variant="ghost"
className={cn(
'zd:relative zd:flex zd:h-[68px] zd:w-full zd:items-center zd:justify-center zd:gap-2 zd:overflow-hidden zd:rounded-2xl zd:px-4',
'zd:shadow-[inset_0_-4px_4px_0_rgba(255,255,255,0.1),inset_0_3px_4px_0_rgba(0,0,0,0.02)]',
className,
)}
{...rest}
>
<Icon
name="lineLoading"
className="zd:size-4 zd:text-greyScale/50"
data-testid="loading-card-icon"
/>
<Text className="zd:text-body1 zd:text-greyScale/50">{text}</Text>
</Wrapper>
)
}