From f262efdf4a567552e5185bc92094ee5a3f9d3410 Mon Sep 17 00:00:00 2001 From: Fabien Date: Fri, 20 Feb 2026 15:08:17 +0100 Subject: [PATCH 1/4] Add an option to hide the send button in the widget Only the QR code and the decorations remain. This makes more sense in the context of a PoS. Closes #613. Test Plan: yarn test Try it using the paybutton-generator.html page --- paybutton/dev/demo/paybutton-generator.html | 7 ++ react/lib/components/PayButton/PayButton.tsx | 3 + .../PaymentDialog/PaymentDialog.tsx | 3 + react/lib/components/Widget/Widget.tsx | 4 +- .../lib/components/Widget/WidgetContainer.tsx | 3 + react/lib/tests/components/PayButton.test.tsx | 99 +++++++++++++++++++ react/lib/tests/components/Widget.test.tsx | 75 ++++++++++++++ 7 files changed, 193 insertions(+), 1 deletion(-) diff --git a/paybutton/dev/demo/paybutton-generator.html b/paybutton/dev/demo/paybutton-generator.html index f6c41bfd..7cb9f130 100644 --- a/paybutton/dev/demo/paybutton-generator.html +++ b/paybutton/dev/demo/paybutton-generator.html @@ -175,6 +175,11 @@ false-value="false"> +
+ + +
@@ -228,6 +233,7 @@ :on-success="mySuccessFuction" :on-transaction="myTransactionFuction" :disable-altpayment="paybuttonProps.disableAltpayment" + :hide-send-button="paybuttonProps.hideSendButton" :transaction-text="paybuttonProps.transactionText" :auto-close="paybuttonProps.autoClose" :op-return="paybuttonProps.opReturn"> @@ -260,6 +266,7 @@ hideToasts: false, disableEnforceFocus: false, disableAltpayment: false, + hideSendButton: false, contributionOffset: undefined, opReturn:undefined, transactiontext: '', diff --git a/react/lib/components/PayButton/PayButton.tsx b/react/lib/components/PayButton/PayButton.tsx index f46588d1..1d1b4ab4 100644 --- a/react/lib/components/PayButton/PayButton.tsx +++ b/react/lib/components/PayButton/PayButton.tsx @@ -55,6 +55,7 @@ export interface PayButtonProps extends ButtonProps { autoClose?: boolean | number | string; disableAltpayment?:boolean contributionOffset?:number + hideSendButton?: boolean; size?: ButtonSize; sizeScaleAlreadyApplied?: boolean; donationAddress?: string; @@ -89,6 +90,7 @@ export const PayButton = ({ autoClose = false, disableAltpayment, contributionOffset, + hideSendButton, size = 'md', sizeScaleAlreadyApplied = false, donationRate = DEFAULT_DONATION_RATE, @@ -435,6 +437,7 @@ export const PayButton = ({ hoverText={hoverText} disableAltpayment={disableAltpayment} contributionOffset={contributionOffset} + hideSendButton={hideSendButton} autoClose={autoClose} useAltpayment={useAltpayment} setUseAltpayment={setUseAltpayment} diff --git a/react/lib/components/PaymentDialog/PaymentDialog.tsx b/react/lib/components/PaymentDialog/PaymentDialog.tsx index c7b533d1..f4d868b5 100644 --- a/react/lib/components/PaymentDialog/PaymentDialog.tsx +++ b/react/lib/components/PaymentDialog/PaymentDialog.tsx @@ -38,6 +38,7 @@ export interface PaymentDialogProps extends ButtonProps { apiBaseUrl?: string; disableAltpayment?: boolean; contributionOffset?: number; + hideSendButton?: boolean; useAltpayment: boolean setUseAltpayment: Function; txsSocket?: Socket; @@ -99,6 +100,7 @@ export const PaymentDialog = ({ hoverText, disableAltpayment, contributionOffset, + hideSendButton, autoClose = true, useAltpayment, setUseAltpayment, @@ -231,6 +233,7 @@ export const PaymentDialog = ({ hoverText={hoverText} disableAltpayment={disableAltpayment} contributionOffset={contributionOffset} + hideSendButton={hideSendButton} useAltpayment={useAltpayment} setUseAltpayment={setUseAltpayment} setTxsSocket={setTxsSocket} diff --git a/react/lib/components/Widget/Widget.tsx b/react/lib/components/Widget/Widget.tsx index e587e8c4..b005f61d 100644 --- a/react/lib/components/Widget/Widget.tsx +++ b/react/lib/components/Widget/Widget.tsx @@ -115,6 +115,7 @@ export interface WidgetProps { newTxText?: string; transactionText?: string; convertedCurrencyObj?: CurrencyObject; + hideSendButton?: boolean; setConvertedCurrencyObj?: Function; setPaymentId?: Function; } @@ -203,6 +204,7 @@ export const Widget: React.FunctionComponent = props => { donationRate = DEFAULT_DONATION_RATE, setConvertedCurrencyObj = () => {}, setPaymentId, + hideSendButton, } = props; const [loading, setLoading] = useState(true); const [draftAmount, setDraftAmount] = useState("") @@ -1347,7 +1349,7 @@ export const Widget: React.FunctionComponent = props => { ) : null} - {success ? null : ( + {success || hideSendButton ? null : ( { // Use createElement to avoid JSX element-type incompatibility from duplicate React types diff --git a/react/lib/components/Widget/WidgetContainer.tsx b/react/lib/components/Widget/WidgetContainer.tsx index 5ef1e373..35dda3e9 100644 --- a/react/lib/components/Widget/WidgetContainer.tsx +++ b/react/lib/components/Widget/WidgetContainer.tsx @@ -57,6 +57,7 @@ export interface WidgetContainerProps donationAddress?: string donationRate?: number convertedCurrencyObj?: CurrencyObject; + hideSendButton?: boolean; } const snackbarOptionsSuccess: OptionsObject = { @@ -141,6 +142,7 @@ export const WidgetContainer: React.FunctionComponent = donationRate, convertedCurrencyObj, setConvertedCurrencyObj, + hideSendButton, ...widgetProps } = props; const [internalCurrencyObj, setInternalCurrencyObj] = useState(); @@ -426,6 +428,7 @@ export const WidgetContainer: React.FunctionComponent = convertedCurrencyObj={convertedCurrencyObj} setConvertedCurrencyObj={setConvertedCurrencyObj} setPaymentId={setThisPaymentId} + hideSendButton={hideSendButton} /> ); diff --git a/react/lib/tests/components/PayButton.test.tsx b/react/lib/tests/components/PayButton.test.tsx index 23735fd0..1f634969 100644 --- a/react/lib/tests/components/PayButton.test.tsx +++ b/react/lib/tests/components/PayButton.test.tsx @@ -469,3 +469,102 @@ describe('PayButton – UI shows updated amount + QR after reopen', () => { ) }) +describe('PayButton – hideSendButton in dialog', () => { + test.each(CRYPTO_CASES)( + 'send button is hidden in dialog when hideSendButton=true (%s)', + async ({ currency, address }) => { + const user = userEvent.setup() + + render( + + ) + + // Open the dialog + await user.click(screen.getByRole('button', { name: /donate/i })) + + await waitFor(() => { + const { createPayment } = require('../../util'); + expect(createPayment).toHaveBeenCalledTimes(1) + }) + + // Wait for dialog to fully render + await waitFor(() => { + expect(screen.queryByText(/loading/i)).toBeNull() + }) + + // The send button should not be present in the dialog + const sendButton = screen.queryByRole('button', { name: /send with.*wallet/i }) + expect(sendButton).toBeNull() + } + ) + + test.each(CRYPTO_CASES)( + 'send button is visible in dialog when hideSendButton=false (%s)', + async ({ currency, address }) => { + const user = userEvent.setup() + + render( + + ) + + // Open the dialog + await user.click(screen.getByRole('button', { name: /donate/i })) + + await waitFor(() => { + const { createPayment } = require('../../util'); + expect(createPayment).toHaveBeenCalledTimes(1) + }) + + // Wait for dialog to fully render + await waitFor(() => { + expect(screen.queryByText(/loading/i)).toBeNull() + }) + + // The send button should be present in the dialog + const sendButton = await screen.findByRole('button', { name: /send with.*wallet/i }) + expect(sendButton).toBeTruthy() + } + ) + + test.each(CRYPTO_CASES)( + 'send button is visible by default (hideSendButton undefined) (%s)', + async ({ currency, address }) => { + const user = userEvent.setup() + + render( + + ) + + // Open the dialog + await user.click(screen.getByRole('button', { name: /donate/i })) + + await waitFor(() => { + const { createPayment } = require('../../util'); + expect(createPayment).toHaveBeenCalledTimes(1) + }) + + // Wait for dialog to fully render + await waitFor(() => { + expect(screen.queryByText(/loading/i)).toBeNull() + }) + + // The send button should be present in the dialog + const sendButton = await screen.findByRole('button', { name: /send with.*wallet/i }) + expect(sendButton).toBeTruthy() + } + ) +}) diff --git a/react/lib/tests/components/Widget.test.tsx b/react/lib/tests/components/Widget.test.tsx index 63e8a9c6..6b644b75 100644 --- a/react/lib/tests/components/Widget.test.tsx +++ b/react/lib/tests/components/Widget.test.tsx @@ -449,3 +449,78 @@ describe('Widget – loading behaviour (WIP)', () => { }) }) +describe('Widget – hideSendButton', () => { + test.each(CRYPTO_CASES)( + '%s – send button is hidden when hideSendButton=true', + async ({ currency, to }) => { + const { createPayment } = require('../../util'); + (createPayment as jest.Mock).mockResolvedValue('pid-hide-test') + + render( + + ) + + await waitFor(() => { + expect(screen.queryByText(/loading/i)).toBeNull() + }) + + // The send button should not be present + const sendButton = screen.queryByRole('button', { name: /send with.*wallet/i }) + expect(sendButton).toBeNull() + } + ) + + test.each(CRYPTO_CASES)( + '%s – send button is visible when hideSendButton=false', + async ({ currency, to }) => { + const { createPayment } = require('../../util'); + (createPayment as jest.Mock).mockResolvedValue('pid-show-test') + + render( + + ) + + await waitFor(() => { + expect(screen.queryByText(/loading/i)).toBeNull() + }) + + // The send button should be present + const sendButton = await screen.findByRole('button', { name: /send with.*wallet/i }) + expect(sendButton).toBeTruthy() + } + ) + + test.each(CRYPTO_CASES)( + '%s – send button is visible by default (hideSendButton undefined)', + async ({ currency, to }) => { + const { createPayment } = require('../../util'); + (createPayment as jest.Mock).mockResolvedValue('pid-default-test') + + render( + + ) + + await waitFor(() => { + expect(screen.queryByText(/loading/i)).toBeNull() + }) + + // The send button should be present by default + const sendButton = await screen.findByRole('button', { name: /send with.*wallet/i }) + expect(sendButton).toBeTruthy() + } + ) +}) From 2f53bc4ef1bde5637296d041cb91b5f30912be0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Estev=C3=A3o?= Date: Fri, 20 Feb 2026 13:24:25 -0300 Subject: [PATCH 2/4] fix: hide send button as allowed props --- paybutton/src/index.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/paybutton/src/index.tsx b/paybutton/src/index.tsx index d6d911bc..f0769134 100644 --- a/paybutton/src/index.tsx +++ b/paybutton/src/index.tsx @@ -82,6 +82,7 @@ const allowedProps = [ 'currency', 'displayCurrency', 'hideToasts', + 'hideSendButton', 'hoverText', 'onSuccess', 'onTransaction', From 5eaebfd80aacaa4b0d61dac20d75b719ec1fd24e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Estev=C3=A3o?= Date: Fri, 20 Feb 2026 13:24:31 -0300 Subject: [PATCH 3/4] chore: add hide send button docs --- docs/README.md | 29 +++++++++++++++++++++++++++++ docs/zh-cn/README.md | 27 +++++++++++++++++++++++++++ docs/zh-tw/README.md | 29 +++++++++++++++++++++++++++++ 3 files changed, 85 insertions(+) diff --git a/docs/README.md b/docs/README.md index e0cf1965..6701c67e 100644 --- a/docs/README.md +++ b/docs/README.md @@ -842,6 +842,35 @@ disabled = true +## hide-send-button + +> **The ‘hide-send-button’ parameter specifies whether or not the 'Send with XEC/BCH' button should be hidden. + +?> This parameter is optional. Default value is false. Possible values are true or false. + +**Example:** + + +#### ** HTML ** + +```html +hide-send-button="true" +``` + +#### ** JavaScript ** + +```javascript +hideSendButton: true +``` + +#### ** React ** + +```react +hideSendButton = true +``` + + + ## disable-enforce-focus > **The ‘disable-enforce-focus’ parameter is passed to the Dialog material UI component. Setting it to false can help with accessibility with technology such as screen readers but may throw errors on sites running Material UI.** diff --git a/docs/zh-cn/README.md b/docs/zh-cn/README.md index 2e5addaa..d8c7b550 100644 --- a/docs/zh-cn/README.md +++ b/docs/zh-cn/README.md @@ -809,6 +809,33 @@ disabled = true +## hide-send-button + +> **参数'hide-send-button'指定是否隐藏'使用 XEC/BCH 发送'按钮。** + +?> 此参数是可选的。默认值为false。可能的值为true或false。 + +**示例:** + + +#### ** HTML ** + +```html +hide-send-button="true" +``` + +#### ** JavaScript ** + +```javascript +hideSendButton: true +``` + +#### ** React ** + +```react +hideSendButton = true +``` + ## disable-enforce-focus diff --git a/docs/zh-tw/README.md b/docs/zh-tw/README.md index c93271f1..4afb8032 100644 --- a/docs/zh-tw/README.md +++ b/docs/zh-tw/README.md @@ -809,6 +809,35 @@ disabled = true +## hide-send-button + +> **參數'hide-send-button'指定是否隱藏'使用 XEC/BCH 發送'按鈕。** + +?> 此參數是可選的。默認值為false。可能的值為true或false。 + +**範例:** + + +#### ** HTML ** + +```html +hide-send-button="true" +``` + +#### ** JavaScript ** + +```javascript +hideSendButton: true +``` + +#### ** React ** + +```react +hideSendButton = true +``` + + + ## disable-enforce-focus > **參數'disable-enforce-focus'被傳遞給 Dialog material UI 組件。將其設定為 false 可以幫助提高如螢幕閱讀器等技術的可訪問性,但可能會在運行 Material UI 的網站上引發錯誤。** From b12c68e8e0de61af89ecde5d84271f8eea81834b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Estev=C3=A3o?= Date: Fri, 20 Feb 2026 13:29:45 -0300 Subject: [PATCH 4/4] fix: wrong docs --- docs/README.md | 6 +++--- docs/zh-cn/README.md | 6 +++--- docs/zh-tw/README.md | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/README.md b/docs/README.md index 6701c67e..79fefac2 100644 --- a/docs/README.md +++ b/docs/README.md @@ -825,19 +825,19 @@ randomSatoshis = true #### ** HTML ** ```html -disabled="true" +hide-toasts="true" ``` #### ** JavaScript ** ```javascript -disabled: true +hideToasts: true ``` #### ** React ** ```react -disabled = true +hideToasts = true ``` diff --git a/docs/zh-cn/README.md b/docs/zh-cn/README.md index d8c7b550..dc86beaf 100644 --- a/docs/zh-cn/README.md +++ b/docs/zh-cn/README.md @@ -792,19 +792,19 @@ randomSatoshis = true #### ** HTML ** ```html -disabled="true" +hide-toasts="true" ``` #### ** JavaScript ** ```javascript -disabled: true +hideToasts: true ``` #### ** React ** ```react -disabled = true +hideToasts = true ``` diff --git a/docs/zh-tw/README.md b/docs/zh-tw/README.md index 4afb8032..4d004665 100644 --- a/docs/zh-tw/README.md +++ b/docs/zh-tw/README.md @@ -792,19 +792,19 @@ randomSatoshis = true #### ** HTML ** ```html -disabled="true" +hide-toasts="true" ``` #### ** JavaScript ** ```javascript -disabled: true +hideToasts: true ``` #### ** React ** ```react -disabled = true +hideToasts = true ```