From c05f7cc7fadb07fc96f87e666f168bc3eaa3ef0b Mon Sep 17 00:00:00 2001 From: Michael Bumann Date: Fri, 26 Jul 2024 23:56:57 +0200 Subject: [PATCH 1/4] fix: button usage for links Button tags in forms submit the form. This means clicking the "Buy Bitcoin" link did not open the link but actually submit the form. According to the HTML spec a button tag must also not be nested into a hyperlink. --- frontend/src/components/ui/button.tsx | 26 +- .../channels/IncreaseIncomingCapacity.tsx | 326 +++++++++-------- .../channels/IncreaseOutgoingCapacity.tsx | 340 +++++++++--------- 3 files changed, 367 insertions(+), 325 deletions(-) diff --git a/frontend/src/components/ui/button.tsx b/frontend/src/components/ui/button.tsx index 84922957..4e076e5a 100644 --- a/frontend/src/components/ui/button.tsx +++ b/frontend/src/components/ui/button.tsx @@ -1,7 +1,9 @@ import { Slot } from "@radix-ui/react-slot"; import { cva, type VariantProps } from "class-variance-authority"; import * as React from "react"; +import { Link } from "react-router-dom"; +import ExternalLink from "src/components/ExternalLink"; import { cn } from "src/lib/utils"; const buttonVariants = cva( @@ -56,5 +58,27 @@ const Button = React.forwardRef( ); Button.displayName = "Button"; +interface LinkProps extends ButtonProps { + to: string; +} +const ExternalLinkButton = React.forwardRef( + ({ className, variant, size, asChild = false, ...props }, ref) => { + const Comp = asChild ? Slot : ExternalLink; + const _className = cn(buttonVariants({ variant, size, className })); + + return ; + } +); + +const LinkButton = React.forwardRef( + ({ className, variant, size, asChild = false, ...props }, ref) => { + const Comp = asChild ? Slot : Link; + const _className = cn(buttonVariants({ variant, size, className })); + + return ; + } +); + +//const ExternalLinkButton = LinkButton // eslint-disable-next-line react-refresh/only-export-components -export { Button, buttonVariants }; +export { Button, LinkButton, ExternalLinkButton, buttonVariants }; diff --git a/frontend/src/screens/channels/IncreaseIncomingCapacity.tsx b/frontend/src/screens/channels/IncreaseIncomingCapacity.tsx index 3dc200e2..a38c5313 100644 --- a/frontend/src/screens/channels/IncreaseIncomingCapacity.tsx +++ b/frontend/src/screens/channels/IncreaseIncomingCapacity.tsx @@ -4,7 +4,11 @@ import { Link, useNavigate } from "react-router-dom"; import AppHeader from "src/components/AppHeader"; import ExternalLink from "src/components/ExternalLink"; import Loading from "src/components/Loading"; -import { Button } from "src/components/ui/button"; +import { + Button, + ExternalLinkButton, + LinkButton, +} from "src/components/ui/button"; import { Checkbox } from "src/components/ui/checkbox"; import { Input } from "src/components/ui/input"; import { Label } from "src/components/ui/label"; @@ -198,177 +202,181 @@ function NewChannelInternal({ } /> -
-
- - {order.amount && +order.amount < 200_000 && ( -

- For a smooth experience consider a opening a channel of 200k sats - in size or more.{" "} - - Learn more - -

- )} - { - setAmount(e.target.value.trim()); - }} - /> -
- {presetAmounts.map((amount) => ( -
setAmount(amount.toString())} - > - {formatAmount(amount * 1000, 0)} -
- ))} +
+ +
+ + {order.amount && +order.amount < 200_000 && ( +

+ For a smooth experience consider a opening a channel of 200k + sats in size or more.{" "} + + Learn more + +

+ )} + { + setAmount(e.target.value.trim()); + }} + /> +
+ {presetAmounts.map((amount) => ( +
setAmount(amount.toString())} + > + {formatAmount(amount * 1000, 0)} +
+ ))} +
-
- {showAdvanced && ( - <> -
- {selectedPeer && ( -
- - + setSelectedPeer( + channelPeerSuggestions.find( + (x) => getPeerKey(x) === value + ) ) - .map((peer) => ( - -
+ } + > + + + + + {channelPeerSuggestions + .filter( + (peer) => + peer.network === network && + peer.paymentMethod === order.paymentMethod + ) + .map((peer) => ( +
- {peer.name !== "Custom" && ( - - )} -
- {peer.name} - - Min.{" "} - {new Intl.NumberFormat().format( - peer.minimumChannelSize - )} - sats - - Max.{" "} - {new Intl.NumberFormat().format( - peer.maximumChannelSize - )}{" "} - sats - +
+ {peer.name !== "Custom" && ( + + )} +
+ {peer.name} + + Min.{" "} + {new Intl.NumberFormat().format( + peer.minimumChannelSize + )} + sats + + Max.{" "} + {new Intl.NumberFormat().format( + peer.maximumChannelSize + )}{" "} + sats + +
-
-
- ))} -
- - {selectedPeer.name === "Custom" && ( - <> -
- - )} -
+
+ ))} + + + {selectedPeer.name === "Custom" && ( + <> +
+ + )} +
+ )} +
+ {order.paymentMethod === "lightning" && ( + )} -
- {order.paymentMethod === "lightning" && ( - - )} -
- setPublic(!order.isPublic)} - className="mr-2" - /> -
- -

- Only enable if you want to receive keysend payments. (e.g. - podcasting) -

+
+ setPublic(!order.isPublic)} + className="mr-2" + /> +
+ +

+ Only enable if you want to receive keysend payments. (e.g. + podcasting) +

+
-
- - )} - {!showAdvanced && ( - - )} - + + )} + {!showAdvanced && ( + + )} + + +

Other options

- - - - - - + + Increase spending balance + + + Buy Bitcoin +
- +
); } diff --git a/frontend/src/screens/channels/IncreaseOutgoingCapacity.tsx b/frontend/src/screens/channels/IncreaseOutgoingCapacity.tsx index 11360065..0bac2652 100644 --- a/frontend/src/screens/channels/IncreaseOutgoingCapacity.tsx +++ b/frontend/src/screens/channels/IncreaseOutgoingCapacity.tsx @@ -4,7 +4,11 @@ import { Link, useNavigate } from "react-router-dom"; import AppHeader from "src/components/AppHeader"; import ExternalLink from "src/components/ExternalLink"; import Loading from "src/components/Loading"; -import { Button } from "src/components/ui/button"; +import { + Button, + ExternalLinkButton, + LinkButton, +} from "src/components/ui/button"; import { Checkbox } from "src/components/ui/checkbox"; import { Input } from "src/components/ui/input"; import { Label } from "src/components/ui/label"; @@ -208,184 +212,190 @@ function NewChannelInternal({ network }: { network: Network }) {
} /> -
-
- - {order.amount && +order.amount < 200_000 && ( -

- For a smooth experience consider a opening a channel of 200k sats - in size or more.{" "} - - Learn more - -

- )} - { - setAmount(e.target.value.trim()); - }} - /> -
- Current savings balance:{" "} - {new Intl.NumberFormat().format(balances.onchain.spendable)} sats -
-
- {presetAmounts.map((amount) => ( -
setAmount(amount.toString())} - > - {formatAmount(amount * 1000, 0)} -
- ))} +
+ +
+ + {order.amount && +order.amount < 200_000 && ( +

+ For a smooth experience consider a opening a channel of 200k + sats in size or more.{" "} + + Learn more + +

+ )} + { + setAmount(e.target.value.trim()); + }} + /> +
+ Current savings balance:{" "} + {new Intl.NumberFormat().format(balances.onchain.spendable)} sats +
+
+ {presetAmounts.map((amount) => ( +
setAmount(amount.toString())} + > + {formatAmount(amount * 1000, 0)} +
+ ))} +
-
- {showAdvanced && ( - <> -
- {selectedPeer && - order.paymentMethod === "onchain" && - selectedPeer.pubkey === order.pubkey && ( -
- - + setSelectedPeer( + channelPeerSuggestions.find( + (x) => getPeerKey(x) === value + ) ) - ) - } - > - - - - - {channelPeerSuggestions - .filter( - (peer) => - peer.network === network && - peer.paymentMethod === order.paymentMethod - ) - .map((peer) => ( - -
+ } + > + + + + + {channelPeerSuggestions + .filter( + (peer) => + peer.network === network && + peer.paymentMethod === order.paymentMethod + ) + .map((peer) => ( +
- {peer.name !== "Custom" && ( - - )} -
- {peer.name} - {peer.minimumChannelSize > 0 && ( - - Min.{" "} - {new Intl.NumberFormat().format( - peer.minimumChannelSize - )}{" "} - sats - +
+ {peer.name !== "Custom" && ( + )} +
+ {peer.name} + {peer.minimumChannelSize > 0 && ( + + Min.{" "} + {new Intl.NumberFormat().format( + peer.minimumChannelSize + )}{" "} + sats + + )} +
-
-
- ))} -
- - {selectedPeer.name === "Custom" && ( - <> -
- - )} -
- )} -
- {order.paymentMethod === "onchain" && ( - - )} + + ))} + + + {selectedPeer.name === "Custom" && ( + <> +
+ + )} +
+ )} +
+ {order.paymentMethod === "onchain" && ( + + )} -
- setPublic(!order.isPublic)} - className="mr-2" - /> -
- -

- Enable if you want to receive keysend payments. (e.g. - podcasting) -

+
+ setPublic(!order.isPublic)} + className="mr-2" + /> +
+ +

+ Enable if you want to receive keysend payments. (e.g. + podcasting) +

+
-
- - )} - {!showAdvanced && ( - - )} - + + )} + {!showAdvanced && ( + + )} + +

Other options

- - - - - - + + Increase receiving capacity + + + Buy Bitcoin +
- +
); } From b5e75903a5c3c1e30ac0a842f98c30469c1623df Mon Sep 17 00:00:00 2001 From: Roland Bewick Date: Sat, 27 Jul 2024 13:07:06 +0700 Subject: [PATCH 2/4] fix: new button component linter errors --- frontend/src/components/ui/button.tsx | 29 ++++++++++++++++----------- 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/frontend/src/components/ui/button.tsx b/frontend/src/components/ui/button.tsx index 4e076e5a..26f5dfd9 100644 --- a/frontend/src/components/ui/button.tsx +++ b/frontend/src/components/ui/button.tsx @@ -58,27 +58,32 @@ const Button = React.forwardRef( ); Button.displayName = "Button"; -interface LinkProps extends ButtonProps { +interface LinkProps extends VariantProps { to: string; + className?: string; } const ExternalLinkButton = React.forwardRef( - ({ className, variant, size, asChild = false, ...props }, ref) => { - const Comp = asChild ? Slot : ExternalLink; - const _className = cn(buttonVariants({ variant, size, className })); - - return ; + ({ className, variant, size, ...props }, _ref) => { + return ( + + ); } ); const LinkButton = React.forwardRef( - ({ className, variant, size, asChild = false, ...props }, ref) => { - const Comp = asChild ? Slot : Link; - const _className = cn(buttonVariants({ variant, size, className })); - - return ; + ({ className, variant, size, ...props }, _ref) => { + return ( + + ); } ); //const ExternalLinkButton = LinkButton // eslint-disable-next-line react-refresh/only-export-components -export { Button, LinkButton, ExternalLinkButton, buttonVariants }; +export { Button, buttonVariants, ExternalLinkButton, LinkButton }; From 19a0c85072f19ced1d196c0f10eafe5c63b8dce2 Mon Sep 17 00:00:00 2001 From: Roland Bewick Date: Sat, 27 Jul 2024 13:10:01 +0700 Subject: [PATCH 3/4] fix: prettier error --- frontend/src/screens/channels/first/FirstChannel.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/screens/channels/first/FirstChannel.tsx b/frontend/src/screens/channels/first/FirstChannel.tsx index 9b757b97..297fe3c8 100644 --- a/frontend/src/screens/channels/first/FirstChannel.tsx +++ b/frontend/src/screens/channels/first/FirstChannel.tsx @@ -147,8 +147,8 @@ export function FirstChannel() {

After paying a lightning invoice to cover on-chain fees, - you'll immediately be able to receive and send bitcoin with your - Hub. + you'll immediately be able to receive and send bitcoin with + your Hub.

)} From f9eec24eaced1084117e541b8b5bdc512ebfa0a6 Mon Sep 17 00:00:00 2001 From: Roland Bewick Date: Sat, 27 Jul 2024 13:12:44 +0700 Subject: [PATCH 4/4] fix: tsc error --- frontend/src/components/ui/button.tsx | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/frontend/src/components/ui/button.tsx b/frontend/src/components/ui/button.tsx index 26f5dfd9..632ce617 100644 --- a/frontend/src/components/ui/button.tsx +++ b/frontend/src/components/ui/button.tsx @@ -58,10 +58,12 @@ const Button = React.forwardRef( ); Button.displayName = "Button"; -interface LinkProps extends VariantProps { - to: string; - className?: string; -} +type LinkProps = React.PropsWithChildren< + VariantProps & { + to: string; + className?: string; + } +>; const ExternalLinkButton = React.forwardRef( ({ className, variant, size, ...props }, _ref) => { return (