Skip to content

Commit 56d95ca

Browse files
feat(packages): borrow activity card (#288)
1 parent 40d67c6 commit 56d95ca

File tree

12 files changed

+566
-27
lines changed

12 files changed

+566
-27
lines changed

package-lock.json

Lines changed: 66 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/babylon-core-ui/src/components/BorrowCard/BorrowCard.tsx

Lines changed: 21 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,43 @@
11
import { Card } from "../Card";
22
import { IconButton } from "../Button";
33
import { PlusIcon } from "../Icons";
4+
import type { PropsWithChildren } from "react";
45

56
/**
6-
* BorrowCard component for initiating new borrow positions
7+
* BorrowCard component - Container for vault borrow positions with add button
78
*
89
* @example
910
* ```tsx
10-
* <BorrowCard
11-
* onNewBorrow={() => handleBorrow()}
12-
* title=""
13-
* description=""
14-
* />
11+
* <BorrowCard onNewBorrow={() => handleBorrow()}>
12+
* <ActivityCard data={activityData} />
13+
* <ActivityCard data={activityData} />
14+
* </BorrowCard>
1515
* ```
1616
*/
1717
export interface BorrowCardProps {
1818
onNewBorrow?: () => void;
19-
title?: string;
20-
description?: string;
2119
className?: string;
2220
}
2321

2422
export function BorrowCard({
2523
onNewBorrow,
26-
title = "",
27-
description = "",
28-
className
29-
}: BorrowCardProps) {
24+
className,
25+
children,
26+
}: PropsWithChildren<BorrowCardProps>) {
3027
return (
3128
<Card className={className}>
32-
<div className="flex flex-col items-center justify-center gap-4 py-8">
33-
<IconButton
34-
variant="outlined"
35-
size="large"
36-
onClick={onNewBorrow}
37-
aria-label="Create new borrow"
38-
>
39-
<PlusIcon />
40-
</IconButton>
41-
<div className="text-center">
42-
<h3 className="text-lg font-medium text-accent-primary">{title}</h3>
43-
<p className="text-sm text-accent-secondary">{description}</p>
29+
<div className="flex flex-col gap-4">
30+
{children}
31+
32+
<div className="flex justify-center py-4">
33+
<IconButton
34+
variant="outlined"
35+
size="large"
36+
onClick={onNewBorrow}
37+
aria-label="Create new borrow position"
38+
>
39+
<PlusIcon />
40+
</IconButton>
4441
</div>
4542
</div>
4643
</Card>
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
import type { Meta, StoryObj } from "@storybook/react";
2+
import { ProviderItem } from "./ProviderItem";
3+
4+
const meta = {
5+
title: "Elements/ProviderItem",
6+
component: ProviderItem,
7+
parameters: {
8+
layout: "centered",
9+
},
10+
tags: ["autodocs"],
11+
argTypes: {
12+
name: {
13+
control: "text",
14+
description: "Provider name",
15+
},
16+
icon: {
17+
control: "text",
18+
description: "Icon URL or React node",
19+
},
20+
iconAlt: {
21+
control: "text",
22+
description: "Alt text for icon",
23+
},
24+
className: {
25+
control: "text",
26+
description: "Additional CSS classes",
27+
},
28+
},
29+
} satisfies Meta<typeof ProviderItem>;
30+
31+
export default meta;
32+
type Story = StoryObj<typeof meta>;
33+
34+
// Bitcoin icon SVG as data URI for examples
35+
const bitcoinIcon = "data:image/svg+xml,%3Csvg viewBox='0 0 24 24' fill='%23FF7C2A' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M23.638 14.904c-1.602 6.43-8.113 10.34-14.542 8.736C2.67 22.05-1.244 15.525.362 9.105 1.962 2.67 8.475-1.243 14.9.358c6.43 1.605 10.342 8.115 8.738 14.548v-.002zm-6.35-4.613c.24-1.59-.974-2.45-2.64-3.03l.54-2.153-1.315-.33-.525 2.107c-.345-.087-.705-.167-1.064-.25l.526-2.127-1.32-.33-.54 2.165c-.285-.067-.565-.132-.84-.2l-1.815-.45-.35 1.407s.975.225.955.236c.535.136.63.486.615.766l-1.477 5.92c-.075.166-.24.406-.614.314.015.02-.96-.24-.96-.24l-.66 1.51 1.71.426.93.242-.54 2.19 1.32.327.54-2.17c.36.1.705.19 1.05.273l-.51 2.154 1.32.33.545-2.19c2.24.427 3.93.257 4.64-1.774.57-1.637-.03-2.58-1.217-3.196.854-.193 1.5-.76 1.68-1.93h.01zm-3.01 4.22c-.404 1.64-3.157.75-4.05.53l.72-2.9c.896.23 3.757.67 3.33 2.37zm.41-4.24c-.37 1.49-2.662.735-3.405.55l.654-2.64c.744.18 3.137.524 2.75 2.084v.006z'/%3E%3C/svg%3E";
36+
37+
export const Default: Story = {
38+
args: {
39+
name: "Ironclad BTC",
40+
icon: bitcoinIcon,
41+
},
42+
};
43+
44+
export const WithoutIcon: Story = {
45+
args: {
46+
name: "Genesis Vault",
47+
},
48+
};
49+
50+
export const LongName: Story = {
51+
args: {
52+
name: "Atlas Custody Provider",
53+
icon: bitcoinIcon,
54+
},
55+
};
56+
57+
export const MultipleProviders: Story = {
58+
args: {
59+
name: "Ironclad BTC",
60+
icon: bitcoinIcon,
61+
},
62+
render: () => (
63+
<div className="flex gap-4">
64+
<ProviderItem name="Ironclad BTC" icon={bitcoinIcon} />
65+
<ProviderItem name="Atlas Custody" icon={bitcoinIcon} />
66+
<ProviderItem name="Genesis Vault" icon={bitcoinIcon} />
67+
</div>
68+
),
69+
};
70+
71+
export const InCard: Story = {
72+
args: {
73+
name: "Ironclad BTC",
74+
icon: bitcoinIcon,
75+
},
76+
render: () => (
77+
<div className="w-96 bg-secondary-highlight p-4 rounded">
78+
<div className="flex flex-col gap-3">
79+
<span className="text-sm text-accent-secondary">Vault Provider(s)</span>
80+
<div className="flex gap-4">
81+
<ProviderItem name="Ironclad BTC" icon={bitcoinIcon} />
82+
<ProviderItem name="Atlas Custody" icon={bitcoinIcon} />
83+
</div>
84+
</div>
85+
</div>
86+
),
87+
};
88+
89+
export const WithCustomIcon: Story = {
90+
args: {
91+
name: "Custom Provider",
92+
icon: (
93+
<div className="w-8 h-8 bg-gradient-to-br from-purple-500 to-pink-500 rounded-full flex items-center justify-center text-white text-xs font-bold">
94+
CP
95+
</div>
96+
),
97+
},
98+
};
99+
100+
export const Grid: Story = {
101+
args: {
102+
name: "Ironclad BTC",
103+
icon: bitcoinIcon,
104+
},
105+
render: () => (
106+
<div className="grid grid-cols-3 gap-4">
107+
<ProviderItem name="Ironclad BTC" icon={bitcoinIcon} />
108+
<ProviderItem name="Atlas Custody" icon={bitcoinIcon} />
109+
<ProviderItem name="Genesis Vault" icon={bitcoinIcon} />
110+
<ProviderItem name="Morpho Vault" icon={bitcoinIcon} />
111+
<ProviderItem name="Compound V3" icon={bitcoinIcon} />
112+
<ProviderItem name="Aave V3" icon={bitcoinIcon} />
113+
</div>
114+
),
115+
};
116+
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
interface ProviderItemProps {
2+
name: string;
3+
icon?: string | React.ReactNode;
4+
iconAlt?: string;
5+
className?: string;
6+
}
7+
8+
export function ProviderItem({
9+
name,
10+
icon,
11+
iconAlt,
12+
className = "",
13+
}: ProviderItemProps) {
14+
return (
15+
<div className={`flex flex-col items-center gap-2 ${className}`}>
16+
{icon && (
17+
<div className="flex items-center justify-center w-8 h-8 flex-shrink-0">
18+
{typeof icon === "string" ? (
19+
<img
20+
src={icon}
21+
alt={iconAlt || name}
22+
className="w-full h-full rounded-full object-cover"
23+
/>
24+
) : (
25+
icon
26+
)}
27+
</div>
28+
)}
29+
<span className="text-xs text-accent-primary font-normal text-center">
30+
{name}
31+
</span>
32+
</div>
33+
);
34+
}
35+
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export { ProviderItem } from "./ProviderItem";
2+
export { ProviderItem as VaultProviderItem } from "./ProviderItem";
3+

0 commit comments

Comments
 (0)