Skip to content

Commit 22a0718

Browse files
feat(packages): borrow page add new borrow button (#287)
1 parent 9b99e0f commit 22a0718

File tree

11 files changed

+214
-1
lines changed

11 files changed

+214
-1
lines changed
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import type { Meta, StoryObj } from "@storybook/react";
2+
import { BorrowCard } from "./BorrowCard";
3+
4+
const meta: Meta<typeof BorrowCard> = {
5+
title: "Components/Cards/BorrowCard",
6+
component: BorrowCard,
7+
tags: ["autodocs"],
8+
parameters: {
9+
docs: {
10+
description: {
11+
component: "A card component for creating new borrow positions in the vault application.",
12+
},
13+
},
14+
},
15+
};
16+
17+
export default meta;
18+
type Story = StoryObj<typeof meta>;
19+
20+
export const Default: Story = {
21+
args: {
22+
onNewBorrow: () => console.log("New borrow clicked"),
23+
},
24+
};
25+
26+
export const CustomText: Story = {
27+
args: {
28+
title: "Start Borrowing",
29+
description: "Create your first borrow position to get started",
30+
onNewBorrow: () => alert("Borrow flow started"),
31+
},
32+
};
33+
34+
export const WithCustomStyling: Story = {
35+
args: {
36+
className: "border-2 border-primary-light",
37+
onNewBorrow: () => console.log("Custom styled borrow"),
38+
},
39+
};
40+
41+
export const Interactive: Story = {
42+
args: {
43+
title: "New Vault Borrow",
44+
description: "Click the plus button to create a new borrow position",
45+
onNewBorrow: () => {
46+
console.log("Borrow action triggered!");
47+
alert("This would open the borrow modal");
48+
},
49+
},
50+
};
51+
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import { Card } from "../Card";
2+
import { IconButton } from "../Button";
3+
import { PlusIcon } from "../Icons";
4+
5+
/**
6+
* BorrowCard component for initiating new borrow positions
7+
*
8+
* @example
9+
* ```tsx
10+
* <BorrowCard
11+
* onNewBorrow={() => handleBorrow()}
12+
* title=""
13+
* description=""
14+
* />
15+
* ```
16+
*/
17+
export interface BorrowCardProps {
18+
onNewBorrow?: () => void;
19+
title?: string;
20+
description?: string;
21+
className?: string;
22+
}
23+
24+
export function BorrowCard({
25+
onNewBorrow,
26+
title = "",
27+
description = "",
28+
className
29+
}: BorrowCardProps) {
30+
return (
31+
<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>
44+
</div>
45+
</div>
46+
</Card>
47+
);
48+
}
49+
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export { BorrowCard } from "./BorrowCard";
2+
export type { BorrowCardProps } from "./BorrowCard";
3+
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 { PlusIcon } from "./common/PlusIcon";
3+
4+
const meta: Meta<typeof PlusIcon> = {
5+
title: "Components/Icons/PlusIcon",
6+
component: PlusIcon,
7+
tags: ["autodocs"],
8+
argTypes: {
9+
size: {
10+
control: { type: "number", min: 8, max: 48, step: 2 },
11+
defaultValue: 14,
12+
},
13+
variant: {
14+
control: "select",
15+
options: ["default", "primary", "secondary", "error", "success", "accent-primary", "accent-secondary"],
16+
},
17+
},
18+
};
19+
20+
export default meta;
21+
type Story = StoryObj<typeof meta>;
22+
23+
export const Default: Story = {
24+
args: {
25+
size: 14,
26+
variant: "default",
27+
},
28+
};
29+
30+
export const Large: Story = {
31+
args: {
32+
size: 24,
33+
variant: "primary",
34+
},
35+
};
36+
37+
export const AllVariants: Story = {
38+
render: () => (
39+
<div className="flex gap-4 items-center">
40+
<PlusIcon variant="default" />
41+
<PlusIcon variant="primary" />
42+
<PlusIcon variant="secondary" />
43+
<PlusIcon variant="error" />
44+
<PlusIcon variant="success" />
45+
<PlusIcon variant="accent-primary" />
46+
<PlusIcon variant="accent-secondary" />
47+
</div>
48+
),
49+
};
50+
51+
export const DifferentSizes: Story = {
52+
render: () => (
53+
<div className="flex gap-4 items-center">
54+
<PlusIcon size={12} />
55+
<PlusIcon size={14} />
56+
<PlusIcon size={20} />
57+
<PlusIcon size={24} />
58+
<PlusIcon size={32} />
59+
</div>
60+
),
61+
};
62+
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { IconProps, iconColorVariants } from "../index";
2+
import { twJoin } from "tailwind-merge";
3+
4+
export const PlusIcon = ({
5+
className = "",
6+
size = 14,
7+
variant = "default",
8+
color
9+
}: IconProps) => {
10+
const colorClass = color || iconColorVariants[variant];
11+
12+
return (
13+
<svg
14+
style={{ width: size, height: size }}
15+
viewBox="0 0 14 14"
16+
fill="none"
17+
xmlns="http://www.w3.org/2000/svg"
18+
className={twJoin("transition-opacity duration-200", colorClass, className)}
19+
>
20+
<path
21+
d="M14 8H8V14H6V8H0V6H6V0H8V6H14V8Z"
22+
fill="currentColor"
23+
/>
24+
</svg>
25+
);
26+
};
27+

packages/babylon-core-ui/src/components/Icons/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ export { CloseIcon } from "./common/CloseIcon";
3434
export { WarningIcon } from "./common/WarningIcon";
3535
export { CollapseIcon } from "./common/CollapseIcon";
3636
export { OpenIcon } from "./common/OpenIcon";
37+
export { PlusIcon } from "./common/PlusIcon";
3738
export { ChevronLeftIcon } from "./common/ChevronLeftIcon";
3839
export { BugReportIcon } from "./common/BugReportIcon";
3940
export { ThemeIcon } from "./common/ThemeIcon";

packages/babylon-core-ui/src/components/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@ export { Copy } from './Copy';
22
export { Toggle } from './Toggle';
33
export { DisplayHash } from './DisplayHash';
44
export * from './Avatar';
5+
export * from './BorrowCard';
56
export * from './Text';
67

packages/babylon-core-ui/src/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ export * from "./components/Card";
1717
export * from "./components/Toggle";
1818
export * from "./components/List";
1919
export * from "./components/Badge";
20+
export * from "./components/BorrowCard";
2021
export * from "./components/SubSection";
2122
export * from "./components/CounterButton";
2223
export * from "./components/Menu";

routes/vault/src/VaultLayout.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
import { Borrow } from "./components/ui";
2+
13
export default function VaultLayout() {
24
return (
35
<div className="container mx-auto flex max-w-[760px] flex-1 flex-col gap-12 px-4">
4-
6+
<Borrow />
57
</div>
68
);
79
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { BorrowCard } from "@babylonlabs-io/core-ui";
2+
3+
export function Borrow() {
4+
5+
const handleNewBorrow = () => {
6+
console.log("New borrow clicked");
7+
};
8+
9+
return (
10+
<div className="container mx-auto flex max-w-[760px] flex-1 flex-col gap-8 px-4 py-8">
11+
<BorrowCard onNewBorrow={handleNewBorrow} />
12+
</div>
13+
);
14+
}
15+

0 commit comments

Comments
 (0)