Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Expand Up @@ -65,10 +65,3 @@ export const SingleMax: Story = {
max: 1,
},
};

export const SingleMaxAtCapacity: Story = {
args: {
counter: 1,
max: 1,
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import { twJoin } from "tailwind-merge";
interface CounterButtonProps {
counter: number;
max: number;
onAdd: () => void;
alwaysShowCounter?: boolean;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is no longer needed, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will address this refactor in a follow up PR

onAdd: () => void;
}

export function CounterButton({ counter, max, onAdd, alwaysShowCounter = false }: CounterButtonProps) {
Expand All @@ -15,7 +15,7 @@ export function CounterButton({ counter, max, onAdd, alwaysShowCounter = false }
return (
<div
className={twJoin(
"bg-primary-highlight flex overflow-hidden rounded-md border border-accent-primary",
"bg-primary-highlight flex overflow-hidden rounded-md border border-accent-primary w-fit",
isClickable && "cursor-pointer",
!showsCounter && !isClickable && "hidden",
!showsCounter && "w-10",
Expand All @@ -28,7 +28,10 @@ export function CounterButton({ counter, max, onAdd, alwaysShowCounter = false }
</div>
)}
{showsCounter && (
<div className="flex h-10 items-center border-l border-accent-primary px-2 text-sm sm:px-4 sm:text-base">
<div className={twJoin(
"flex h-10 items-center px-2 text-sm sm:px-4 sm:text-base",
isClickable && "border-l border-accent-primary"
)}>
{counter}/{max}
</div>
)}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,19 @@ export function FinalityProviderItem({ bsnId, bsnName, bsnLogoUrl, provider, onR
return (
<div className="flex flex-row items-center justify-between">
<div className="flex h-10 flex-row gap-2">
<FinalityProviderLogo
logoUrl={provider.logo_url}
rank={provider.rank}
moniker={provider.description?.moniker}
size="lg"
/>
<div className="shrink-0">
<FinalityProviderLogo
logoUrl={provider.logo_url}
rank={provider.rank}
moniker={provider.description?.moniker}
size="lg"
/>
</div>
<div className="flex flex-col justify-center text-accent-primary">
<div className="flex items-center text-xs text-accent-secondary">
{renderBsnLogo()}
<div className="shrink-0">
{renderBsnLogo()}
</div>
{bsnName}
</div>
<Text as="div" className="text-base font-medium text-accent-primary">
Expand All @@ -51,7 +55,7 @@ export function FinalityProviderItem({ bsnId, bsnName, bsnLogoUrl, provider, onR

<button
onClick={() => onRemove(bsnId)}
className="cursor-pointer rounded bg-accent-secondary/20 px-2 py-0.5 text-xs tracking-[0.4px] text-accent-primary"
className="ml-[10px] cursor-pointer rounded bg-accent-secondary/20 px-2 py-0.5 text-xs tracking-[0.4px] text-accent-primary"
>
Remove
</button>
Expand Down
2 changes: 2 additions & 0 deletions packages/babylon-core-ui/src/utils/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const BTC_DECIMAL_PLACES = 8;
export const BBN_DECIMAL_PLACES = 5;
Copy link
Preview

Copilot AI Jul 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is trailing whitespace at the end of the line that should be removed.

Suggested change
export const BBN_DECIMAL_PLACES = 5;
export const BBN_DECIMAL_PLACES = 5;

Copilot uses AI. Check for mistakes.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jonybur linting

Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { SubSection } from "@/components/SubSection";
import { useFormContext, useWatch } from "react-hook-form";

import { calculateTokenValueInCurrency, maxDecimals } from "@/utils/helpers";
import { BTC_DECIMAL_PLACES } from "@/utils/constants";

interface BalanceDetails {
balance: number | string;
Expand Down Expand Up @@ -73,7 +74,7 @@ export const AmountSubsection = ({
onKeyDown={handleKeyDown}
placeholder={placeholder}
autoFocus={autoFocus}
className="w-2/3 bg-transparent text-right text-lg outline-none"
className="w-2/3 bg-transparent text-right text-lg outline-none appearance-none [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none"
/>
</div>
<HiddenField name={fieldName} defaultValue="" />
Expand All @@ -83,7 +84,7 @@ export const AmountSubsection = ({
<div>
Stakable:{" "}
<span className="cursor-default">
{maxDecimals(Number(balanceDetails.balance), balanceDetails.decimals ?? 8)}
{maxDecimals(Number(balanceDetails.balance), balanceDetails.decimals ?? BTC_DECIMAL_PLACES)}
</span>{" "}
{balanceDetails.symbol}
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { FeeItem } from "./FeeItem";
import { BBN_DECIMAL_PLACES } from "../../../utils/constants";

interface BBNFeeAmountProps {
amount: number | string;
Expand All @@ -9,7 +10,7 @@ interface BBNFeeAmountProps {
decimals?: number;
}

export function BBNFeeAmount({ amount, coinSymbol, hint, title, className, decimals = 5 }: BBNFeeAmountProps) {
export function BBNFeeAmount({ amount, coinSymbol, hint, title, className, decimals = BBN_DECIMAL_PLACES }: BBNFeeAmountProps) {
const formattedAmount = typeof amount === "number" ? amount.toFixed(decimals) : amount;

return (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { FeeItem } from "./FeeItem";
import { BTC_DECIMAL_PLACES } from "../../../utils/constants";

interface BTCFeeAmountProps {
amount: number | string;
Expand All @@ -9,16 +10,19 @@ interface BTCFeeAmountProps {
decimals?: number;
}

export function BTCFeeAmount({ amount, coinSymbol, hint, title, className, decimals = 8 }: BTCFeeAmountProps) {
const formattedAmount =
typeof amount === "number"
? amount === 0
? "0"
: (() => {
const str = amount.toFixed(decimals);
return str.replace(/0+$/, "").replace(/\.$/, "");
})()
: amount;
export function BTCFeeAmount({ amount, coinSymbol, hint, title, className, decimals = BTC_DECIMAL_PLACES }: BTCFeeAmountProps) {
let formattedAmount: string;

if (typeof amount === "number") {
if (amount === 0) {
formattedAmount = "0";
} else {
const str = amount.toFixed(decimals);
formattedAmount = str.replace(/0+$/, "").replace(/\.$/, "");
}
} else {
formattedAmount = amount;
}

return (
<FeeItem title={title ?? `${coinSymbol} Network Fee`} hint={hint} className={className}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,7 @@ export function FeeItem({ title, children, className, hint }: FeeItemProps) {
{title}
</Text>

{!hint ? (
<Text as="div" className="flex items-center gap-2">
{children}
</Text>
) : (
{hint ? (
<div className="flex flex-col items-end">
<Text as="div" className="flex items-center gap-2">
{children}
Expand All @@ -34,6 +30,10 @@ export function FeeItem({ title, children, className, hint }: FeeItemProps) {
{hint}
</Text>
</div>
) : (
<Text as="div" className="flex items-center gap-2">
{children}
</Text>
)}
</div>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ export function FeesSection({
feeAmountHint,
total,
totalHint,

bbnFeeAmount,
bbnCoinSymbol,
bbnFeeAmountHint,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Text } from "../../../components/Text";
import { twMerge } from "tailwind-merge";
import { BTC_DECIMAL_PLACES } from "../../../utils/constants";

interface TotalProps {
total: number | string;
Expand All @@ -10,16 +11,18 @@ interface TotalProps {
decimals?: number;
}

export function Total({ total, coinSymbol, hint, title = "Total", className, decimals = 8 }: TotalProps) {
const formattedTotal =
typeof total === "number"
? total === 0
? "0"
: (() => {
const str = total.toFixed(decimals);
return str.replace(/0+$/, "").replace(/\.$/, "");
})()
: total;
export function Total({ total, coinSymbol, hint, title = "Total", className, decimals = BTC_DECIMAL_PLACES }: TotalProps) {
let formattedTotal;
Copy link
Preview

Copilot AI Jul 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The variable formattedTotal should be declared with an explicit type annotation (string) for better type safety and code clarity.

Suggested change
let formattedTotal;
let formattedTotal: string;

Copilot uses AI. Check for mistakes.

if (typeof total === "number") {
if (total === 0) {
formattedTotal = "0";
} else {
const str = total.toFixed(decimals);
formattedTotal = str.replace(/0+$/, "").replace(/\.$/, "");
}
} else {
formattedTotal = total;
}

return (
<div className={twMerge("flex flex-row items-start justify-between text-accent-primary", className)}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@ import type { Meta, StoryObj } from "@storybook/react";

import { PreviewModal } from "./PreviewModal";

const PlaceholderIcon = ({ text, bgColor = "bg-primary-300" }: { text: string; bgColor?: string }) => (
<div className={`${bgColor} flex h-6 w-6 items-center justify-center rounded text-xs font-semibold text-white`}>
{text}
</div>
);

const meta: Meta<typeof PreviewModal> = {
component: PreviewModal,
tags: ["autodocs"],
Expand All @@ -15,25 +21,25 @@ export const Default: Story = {
args: {
open: true,
processing: false,
onClose: () => {},
onProceed: () => {},
onClose: () => { },
onProceed: () => { },
bsns: [
{
icon: <span className="bg-primary-300 h-4 w-4 rounded-full" />,
icon: <PlaceholderIcon text="B1" bgColor="bg-black" />,
name: "BSN 1",
},
{
icon: <span className="bg-primary-300 h-4 w-4 rounded-full" />,
icon: <PlaceholderIcon text="B2" bgColor="bg-black" />,
name: "BSN 2",
},
],
finalityProviders: [
{
icon: <span className="bg-secondary-300 h-4 w-4 rounded-full" />,
icon: <PlaceholderIcon text="F1" bgColor="bg-black" />,
name: "FP 1",
},
{
icon: <span className="bg-secondary-300 h-4 w-4 rounded-full" />,
icon: <PlaceholderIcon text="F2" bgColor="bg-black" />,
name: "FP 2",
},
],
Expand All @@ -42,10 +48,10 @@ export const Default: Story = {
feeRate: "5 sat/vB",
transactionFees: "0.0001 BTC",
term: {
blocks: "100",
duration: "~20 hours",
blocks: "60000 blocks",
duration: "~ 60 weeks",
},
unbonding: "1 day",
unbonding: "~ 1 day",
unbondingFee: "0 BTC",
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,27 @@
import { Dialog, MobileDialog, DialogBody, DialogFooter, DialogHeader } from "@/components/Dialog";
import { Heading } from "@/components/Heading";
import { Text } from "@/components/Text";
import { PropsWithChildren, ReactNode, useEffect, useState } from "react";
import { useIsMobile } from "@/hooks/useIsMobile";
import { PropsWithChildren, ReactNode } from "react";
import { twMerge } from "tailwind-merge";

const toKebabCase = (str: string): string => {
Copy link
Preview

Copilot AI Jul 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The toKebabCase function should be moved to a utilities file rather than being defined inline in this component, as it could be reused elsewhere in the codebase.

Copilot uses AI. Check for mistakes.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jonybur this comment make sense to me

return str
.toLowerCase()
.replace(/[^a-z0-9]+/g, '-')
.replace(/^-+|-+$/g, '');
};

type DialogComponentProps = Parameters<typeof Dialog>[0];

interface ResponsiveDialogProps extends DialogComponentProps {
children?: ReactNode;
}

function useIsMobileView() {
const [isMobile, setIsMobile] = useState(false);

useEffect(() => {
const update = () => setIsMobile(window.innerWidth <= 640);
update();
window.addEventListener("resize", update);
return () => window.removeEventListener("resize", update);
}, []);

return isMobile;
}
const WINDOW_BREAKPOINT = 640;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be moved to a centralised place too. sounds like a constant value which you can use across the codebase

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will address this refactor in a follow up PR


function ResponsiveDialog({ className, ...restProps }: ResponsiveDialogProps) {
const isMobileView = useIsMobileView();
const isMobileView = useIsMobile(WINDOW_BREAKPOINT);
const DialogComponent = isMobileView ? MobileDialog : Dialog;

return <DialogComponent {...restProps} className={twMerge("w-[41.25rem] max-w-full", className)} />;
Expand Down Expand Up @@ -107,7 +104,7 @@
<div className="grid grid-cols-2 items-center gap-4 rounded bg-primary-contrast p-4">
<div className="flex flex-col gap-3">
{bsns.map((bsnItem, index) => (
<div key={`bsn-${index}`} className="flex w-full items-center justify-center gap-2 py-1">
<div key={`bsn-${toKebabCase(bsnItem.name)}-${index}`} className="flex w-full items-center justify-center gap-2 py-1">
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not use the bsn id?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will address this refactor in a follow up PR

{bsnItem.icon}
<Text variant="body2" className="font-medium">
{bsnItem.name}
Expand All @@ -117,7 +114,7 @@
</div>
<div className="flex flex-col gap-3">
{finalityProviders.map((fpItem, index) => (
<div key={`fp-${index}`} className="flex w-full items-center justify-center gap-2 py-1">
<div key={`fp-${toKebabCase(fpItem.name)}-${index}`} className="flex w-full items-center justify-center gap-2 py-1">
{fpItem.icon}
<Text variant="body2" className="font-medium">
{fpItem.name}
Expand Down Expand Up @@ -150,23 +147,21 @@
</Heading>
<Text variant="body2" className="text-secondary">
1. No third party possesses your staked BTC. You are the only one who can unbond and withdraw your stake.
Copy link
Preview

Copilot AI Jul 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The numbered text content should be extracted to constants or props to improve maintainability and potential internationalization support.

Copilot uses AI. Check for mistakes.

<br />
</Text>
<br />
<Text variant="body2" className="text-secondary">
2. Your stake will first be sent to Babylon Genesis for verification (~20 seconds), then you will be
prompted to submit it to the Bitcoin ledger. It will be marked as &apos;Pending&apos; until it receives 10
Bitcoin confirmations.
</Text>
</div>
</DialogBody>
<DialogFooter className="flex gap-4 pb-8 pt-0">
<Button variant="outlined" color="primary" onClick={onClose} className="flex-1">
Cancel
</Button>
<Button variant="contained" color="primary" onClick={onProceed} className="flex-1" disabled={processing}>
<DialogFooter className="flex flex-col gap-4 pb-8 pt-0 sm:flex-row">
<Button variant="contained" color="primary" onClick={onProceed} className="w-full sm:flex-1 sm:order-2" disabled={processing}>
{processing ? "Processing..." : "Proceed to Signing"}
</Button>
<Button variant="outlined" color="primary" onClick={onClose} className="w-full sm:flex-1 sm:order-1">
Cancel
</Button>
</DialogFooter>
</ResponsiveDialog>
);
Expand Down