Skip to content

Commit f8babef

Browse files
Grace-CODE-DGrace-CODE-D
authored andcommitted
Add UI Storybook coverage and centralize streams copy
- Add Select stories covering default, placeholder, disabled, and invalid states using the composed Select API.\n- Add FeeEstimateDialog stories covering normal fees, high-fee warnings, and loading behavior with realistic fee breakdowns.\n- Add AccessibleUnlockAmount stories covering active, cliff-reached, completed, and hidden pause-button states.\n- Move the remaining token filter labels from the streams page into lib/copy/streams.ts.\n\nCloses #967\nCloses #966\nCloses #965\nCloses #964
1 parent 136e2ff commit f8babef

5 files changed

Lines changed: 162 additions & 3 deletions

File tree

‎app/app/streams/page.tsx‎

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,6 @@ import { streamsCopy, type SortOption } from '@/lib/copy/streams'
4646
const SORT_OPTIONS = streamsCopy.filters.sortOptions
4747
const STATUS_FILTERS = streamsCopy.filters.statusFilters
4848

49-
const TOKEN_OPTIONS = ['all', 'XLM', 'USDC', 'EURC'] as const
50-
5149
// Issue #688: read-only card for the Archived tab. Archived streams are
5250
// terminal (cancelled, or fully withdrawn past end_time) so none of the
5351
// active-stream actions (withdraw/cancel/select) apply — just the option to
@@ -481,7 +479,7 @@ function StreamsPage() {
481479

482480
{/* Token filter */}
483481
<div className="flex flex-wrap gap-2">
484-
{TOKEN_OPTIONS.map((t) => (
482+
{streamsCopy.tokenOptions.map((t) => (
485483
<button
486484
key={t}
487485
onClick={() => setParam('token', t)}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import type { Meta, StoryObj } from '@storybook/react'
2+
import { AccessibleUnlockAmount } from './accessible-unlock-amount'
3+
4+
const meta = {
5+
title: 'UI/AccessibleUnlockAmount',
6+
component: AccessibleUnlockAmount,
7+
tags: ['autodocs'],
8+
parameters: { layout: 'centered' },
9+
} satisfies Meta<typeof AccessibleUnlockAmount>
10+
11+
export default meta
12+
type Story = StoryObj<typeof meta>
13+
14+
const base = {
15+
amount: 125_000_000n,
16+
decimals: 6,
17+
symbol: 'USDC',
18+
}
19+
20+
export const Active: Story = {
21+
args: base,
22+
}
23+
24+
export const CliffReached: Story = {
25+
args: {
26+
...base,
27+
amount: 250_000_000n,
28+
isCliffReached: true,
29+
},
30+
}
31+
32+
export const Completed: Story = {
33+
args: {
34+
...base,
35+
amount: 1_000_000_000n,
36+
isCompleted: true,
37+
},
38+
}
39+
40+
export const HiddenPauseButton: Story = {
41+
args: {
42+
...base,
43+
hideButton: true,
44+
},
45+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import type { Meta, StoryObj } from '@storybook/react'
2+
import { FeeEstimateDialog, type FeeBreakdown } from './fee-estimate-dialog'
3+
4+
const meta = {
5+
title: 'UI/FeeEstimateDialog',
6+
component: FeeEstimateDialog,
7+
tags: ['autodocs'],
8+
parameters: { layout: 'centered' },
9+
} satisfies Meta<typeof FeeEstimateDialog>
10+
11+
export default meta
12+
type Story = StoryObj<typeof meta>
13+
14+
const normalFees: FeeBreakdown = {
15+
minFee: 50_000,
16+
bufferFee: 7_500,
17+
totalEstimated: 57_500,
18+
estimatedUsd: 0.007,
19+
}
20+
21+
const highFees: FeeBreakdown = {
22+
minFee: 500_000,
23+
bufferFee: 75_000,
24+
totalEstimated: 575_000,
25+
estimatedUsd: 0.07,
26+
}
27+
28+
const actions = {
29+
onConfirm: () => undefined,
30+
onCancel: () => undefined,
31+
}
32+
33+
export const NormalFee: Story = {
34+
args: {
35+
...actions,
36+
open: true,
37+
fees: normalFees,
38+
action: 'create stream',
39+
averageFee: 100_000,
40+
},
41+
}
42+
43+
export const HighFeeWarning: Story = {
44+
args: {
45+
...actions,
46+
open: true,
47+
fees: highFees,
48+
action: 'withdraw funds',
49+
averageFee: 100_000,
50+
isHighFee: true,
51+
},
52+
}
53+
54+
export const Loading: Story = {
55+
args: {
56+
...actions,
57+
open: true,
58+
fees: normalFees,
59+
action: 'create stream',
60+
loading: true,
61+
},
62+
}

‎components/ui/select.stories.tsx‎

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import type { Meta, StoryObj } from '@storybook/react'
2+
import {
3+
Select,
4+
SelectContent,
5+
SelectItem,
6+
SelectTrigger,
7+
SelectValue,
8+
} from './select'
9+
10+
const meta = {
11+
title: 'UI/Select',
12+
component: Select,
13+
tags: ['autodocs'],
14+
parameters: { layout: 'centered' },
15+
} satisfies Meta<typeof Select>
16+
17+
export default meta
18+
type Story = StoryObj<typeof meta>
19+
20+
function SelectShowcase({ disabled = false, invalid = false, placeholder = 'Choose a token' }: {
21+
disabled?: boolean
22+
invalid?: boolean
23+
placeholder?: string
24+
}) {
25+
return (
26+
<Select disabled={disabled}>
27+
<SelectTrigger aria-invalid={invalid} className="w-48">
28+
<SelectValue placeholder={placeholder} />
29+
</SelectTrigger>
30+
<SelectContent>
31+
<SelectItem value="xlm">XLM</SelectItem>
32+
<SelectItem value="usdc">USDC</SelectItem>
33+
<SelectItem value="eurc">EURC</SelectItem>
34+
</SelectContent>
35+
</Select>
36+
)
37+
}
38+
39+
export const Default: Story = {
40+
render: () => <SelectShowcase />,
41+
}
42+
43+
export const WithPlaceholder: Story = {
44+
render: () => <SelectShowcase placeholder="Select an asset" />,
45+
}
46+
47+
export const Disabled: Story = {
48+
render: () => <SelectShowcase disabled />,
49+
}
50+
51+
export const Invalid: Story = {
52+
render: () => <SelectShowcase invalid />,
53+
}

‎lib/copy/streams.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export type SortOption =
1414
| 'end-desc'
1515

1616
export const streamsCopy = {
17+
tokenOptions: ['all', 'XLM', 'USDC', 'EURC'] as const,
1718
header: {
1819
title: 'Streams',
1920
description: "All streams you've sent or received.",

0 commit comments

Comments
 (0)