diff --git a/packages/babylon-core-ui/src/components/CounterButton/CounterButton.stories.tsx b/packages/babylon-core-ui/src/components/CounterButton/CounterButton.stories.tsx index ff1dbca5..834e0033 100644 --- a/packages/babylon-core-ui/src/components/CounterButton/CounterButton.stories.tsx +++ b/packages/babylon-core-ui/src/components/CounterButton/CounterButton.stories.tsx @@ -38,8 +38,8 @@ export const AlmostAtMax: Story = { export const AtMaxCapacity: Story = { args: { - counter: 5, - max: 5, + counter: 1, + max: 1, }, }; @@ -49,26 +49,4 @@ export const AlwaysShowCounter: Story = { max: 3, alwaysShowCounter: true, }, -}; - -export const AlwaysShowCounterWithValue: Story = { - args: { - counter: 1, - max: 3, - alwaysShowCounter: true, - }, -}; - -export const SingleMax: Story = { - args: { - counter: 0, - max: 1, - }, -}; - -export const SingleMaxAtCapacity: Story = { - args: { - counter: 1, - max: 1, - }, -}; +}; \ No newline at end of file diff --git a/packages/babylon-core-ui/src/components/CounterButton/CounterButton.tsx b/packages/babylon-core-ui/src/components/CounterButton/CounterButton.tsx index 177a1ddd..23f3814a 100644 --- a/packages/babylon-core-ui/src/components/CounterButton/CounterButton.tsx +++ b/packages/babylon-core-ui/src/components/CounterButton/CounterButton.tsx @@ -4,18 +4,18 @@ import { twJoin } from "tailwind-merge"; interface CounterButtonProps { counter: number; max: number; - onAdd: () => void; alwaysShowCounter?: boolean; + onAdd: () => void; } export function CounterButton({ counter, max, onAdd, alwaysShowCounter = false }: CounterButtonProps) { const isClickable = counter < max; - const showsCounter = (0 < counter && 1 < max) || (alwaysShowCounter && counter === 0); + const showsCounter = (0 < counter) || (alwaysShowCounter && counter === 0); return (
)} {showsCounter && ( -
+
{counter}/{max}
)} diff --git a/packages/babylon-core-ui/src/components/SubSection/index.ts b/packages/babylon-core-ui/src/components/SubSection/index.ts deleted file mode 100644 index 54fd90c2..00000000 --- a/packages/babylon-core-ui/src/components/SubSection/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { SubSection } from "./SubSection"; diff --git a/packages/babylon-core-ui/src/elements/FinalityProviderItem/FinalityProviderItem.tsx b/packages/babylon-core-ui/src/elements/FinalityProviderItem/FinalityProviderItem.tsx index 70ee72dd..a86161f1 100644 --- a/packages/babylon-core-ui/src/elements/FinalityProviderItem/FinalityProviderItem.tsx +++ b/packages/babylon-core-ui/src/elements/FinalityProviderItem/FinalityProviderItem.tsx @@ -25,9 +25,22 @@ export function FinalityProviderItem({ bsnId, bsnName, bsnLogoUrl, address, prov if (!provider) return null; const renderBsnLogo = () => { - if (!bsnLogoUrl) return null; + if (bsnLogoUrl) { + return ; + } + + const placeholderLetter = bsnName?.charAt(0).toUpperCase() || "?"; - return ; + return ( + + + {placeholderLetter} + + + ); }; const shortenAddress = (value: string): string => { @@ -54,12 +67,14 @@ export function FinalityProviderItem({ bsnId, bsnName, bsnLogoUrl, address, prov return (
- +
+ +
{renderChainOrAddress()} @@ -70,7 +85,7 @@ export function FinalityProviderItem({ bsnId, bsnName, bsnLogoUrl, address, prov {onRemove ? : null} diff --git a/packages/babylon-core-ui/src/utils/constants.ts b/packages/babylon-core-ui/src/utils/constants.ts new file mode 100644 index 00000000..7d13aa7c --- /dev/null +++ b/packages/babylon-core-ui/src/utils/constants.ts @@ -0,0 +1,2 @@ +export const BTC_DECIMAL_PLACES = 8; +export const BBN_DECIMAL_PLACES = 5; \ No newline at end of file diff --git a/packages/babylon-core-ui/src/widgets/sections/AmountSubsection/AmountSubsection.tsx b/packages/babylon-core-ui/src/widgets/sections/AmountSubsection/AmountSubsection.tsx index fac22c21..bcfe3f17 100644 --- a/packages/babylon-core-ui/src/widgets/sections/AmountSubsection/AmountSubsection.tsx +++ b/packages/babylon-core-ui/src/widgets/sections/AmountSubsection/AmountSubsection.tsx @@ -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; @@ -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" />
@@ -83,7 +84,7 @@ export const AmountSubsection = ({
Stakable:{" "} - {maxDecimals(Number(balanceDetails.balance), balanceDetails.decimals ?? 8)} + {maxDecimals(Number(balanceDetails.balance), balanceDetails.decimals ?? BTC_DECIMAL_PLACES)} {" "} {balanceDetails.symbol}
diff --git a/packages/babylon-core-ui/src/widgets/sections/FeesSection/BBNFeeAmount.tsx b/packages/babylon-core-ui/src/widgets/sections/FeesSection/BBNFeeAmount.tsx index d2695e87..b5c90e94 100644 --- a/packages/babylon-core-ui/src/widgets/sections/FeesSection/BBNFeeAmount.tsx +++ b/packages/babylon-core-ui/src/widgets/sections/FeesSection/BBNFeeAmount.tsx @@ -1,4 +1,5 @@ import { FeeItem } from "./FeeItem"; +import { BBN_DECIMAL_PLACES } from "../../../utils/constants"; interface BBNFeeAmountProps { amount: number | string; @@ -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 ( diff --git a/packages/babylon-core-ui/src/widgets/sections/FeesSection/BTCFeeAmount.tsx b/packages/babylon-core-ui/src/widgets/sections/FeesSection/BTCFeeAmount.tsx index bee0a016..221fbe84 100644 --- a/packages/babylon-core-ui/src/widgets/sections/FeesSection/BTCFeeAmount.tsx +++ b/packages/babylon-core-ui/src/widgets/sections/FeesSection/BTCFeeAmount.tsx @@ -1,4 +1,5 @@ import { FeeItem } from "./FeeItem"; +import { BTC_DECIMAL_PLACES } from "../../../utils/constants"; interface BTCFeeAmountProps { amount: number | string; @@ -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 ( diff --git a/packages/babylon-core-ui/src/widgets/sections/FeesSection/FeeItem.tsx b/packages/babylon-core-ui/src/widgets/sections/FeesSection/FeeItem.tsx index ef763f9c..b1b48681 100644 --- a/packages/babylon-core-ui/src/widgets/sections/FeesSection/FeeItem.tsx +++ b/packages/babylon-core-ui/src/widgets/sections/FeesSection/FeeItem.tsx @@ -21,11 +21,7 @@ export function FeeItem({ title, children, className, hint }: FeeItemProps) { {title} - {!hint ? ( - - {children} - - ) : ( + {hint ? (
{children} @@ -34,6 +30,10 @@ export function FeeItem({ title, children, className, hint }: FeeItemProps) { {hint}
+ ) : ( + + {children} + )}
); diff --git a/packages/babylon-core-ui/src/widgets/sections/FeesSection/FeesSection.tsx b/packages/babylon-core-ui/src/widgets/sections/FeesSection/FeesSection.tsx index 222106e7..80045e34 100644 --- a/packages/babylon-core-ui/src/widgets/sections/FeesSection/FeesSection.tsx +++ b/packages/babylon-core-ui/src/widgets/sections/FeesSection/FeesSection.tsx @@ -30,7 +30,6 @@ export function FeesSection({ feeAmountHint, total, totalHint, - bbnFeeAmount, bbnCoinSymbol, bbnFeeAmountHint, diff --git a/packages/babylon-core-ui/src/widgets/sections/FeesSection/Total.tsx b/packages/babylon-core-ui/src/widgets/sections/FeesSection/Total.tsx index 8e6c591d..adf0f030 100644 --- a/packages/babylon-core-ui/src/widgets/sections/FeesSection/Total.tsx +++ b/packages/babylon-core-ui/src/widgets/sections/FeesSection/Total.tsx @@ -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; @@ -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; + if (typeof total === "number") { + if (total === 0) { + formattedTotal = "0"; + } else { + const str = total.toFixed(decimals); + formattedTotal = str.replace(/0+$/, "").replace(/\.$/, ""); + } + } else { + formattedTotal = total; + } return (
diff --git a/packages/babylon-core-ui/src/widgets/sections/PreviewModal/PreviewModal.stories.tsx b/packages/babylon-core-ui/src/widgets/sections/PreviewModal/PreviewModal.stories.tsx index fa5209e0..6c5d04dd 100644 --- a/packages/babylon-core-ui/src/widgets/sections/PreviewModal/PreviewModal.stories.tsx +++ b/packages/babylon-core-ui/src/widgets/sections/PreviewModal/PreviewModal.stories.tsx @@ -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 }) => ( +
+ {text} +
+); + const meta: Meta = { component: PreviewModal, tags: ["autodocs"], @@ -15,25 +21,25 @@ export const Default: Story = { args: { open: true, processing: false, - onClose: () => {}, - onProceed: () => {}, + onClose: () => { }, + onProceed: () => { }, bsns: [ { - icon: , + icon: , name: "BSN 1", }, { - icon: , + icon: , name: "BSN 2", }, ], finalityProviders: [ { - icon: , + icon: , name: "FP 1", }, { - icon: , + icon: , name: "FP 2", }, ], @@ -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", }, }, diff --git a/packages/babylon-core-ui/src/widgets/sections/PreviewModal/PreviewModal.tsx b/packages/babylon-core-ui/src/widgets/sections/PreviewModal/PreviewModal.tsx index e613c76b..01bb465b 100644 --- a/packages/babylon-core-ui/src/widgets/sections/PreviewModal/PreviewModal.tsx +++ b/packages/babylon-core-ui/src/widgets/sections/PreviewModal/PreviewModal.tsx @@ -3,30 +3,40 @@ import { Card } from "@/components/Card"; 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 => { + let result = ''; + + for (let i = 0; i < str.length; i++) { + const char = str[i].toLowerCase(); + + if ((char >= 'a' && char <= 'z') || (char >= '0' && char <= '9')) { + result += char; + } else if (result.length > 0 && result[result.length - 1] !== '-') { + result += '-'; + } + } + + if (result.endsWith('-')) { + result = result.slice(0, -1); + } + + return result; +}; + type DialogComponentProps = Parameters[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; function ResponsiveDialog({ className, ...restProps }: ResponsiveDialogProps) { - const isMobileView = useIsMobileView(); + const isMobileView = useIsMobile(WINDOW_BREAKPOINT); const DialogComponent = isMobileView ? MobileDialog : Dialog; return ; @@ -107,7 +117,7 @@ export const PreviewModal = ({
{bsns.map((bsnItem, index) => ( -
+
{bsnItem.icon} {bsnItem.name} @@ -117,7 +127,7 @@ export const PreviewModal = ({
{finalityProviders.map((fpItem, index) => ( -
+
{fpItem.icon} {fpItem.name} @@ -150,9 +160,7 @@ export const PreviewModal = ({ 1. No third party possesses your staked BTC. You are the only one who can unbond and withdraw your stake. -
-
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 'Pending' until it receives 10 @@ -160,13 +168,13 @@ export const PreviewModal = ({
- - - + );