mirror of
https://github.com/woocommerce/woocommerce-paypal-payments.git
synced 2025-09-06 13:44:42 +08:00
Add Submit button
This commit is contained in:
parent
bccfe4c436
commit
e3996b1f6e
5 changed files with 341 additions and 36 deletions
|
@ -6,11 +6,6 @@
|
||||||
padding-right: 1em;
|
padding-right: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ppcp-axo-block-watermark-container {
|
|
||||||
float: right;
|
|
||||||
margin-top: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.wc-block-checkout-axo-block-card {
|
.wc-block-checkout-axo-block-card {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
@ -81,3 +76,97 @@
|
||||||
.wc-block-axo-block-card__meta-icon {
|
.wc-block-axo-block-card__meta-icon {
|
||||||
max-height: 25px;
|
max-height: 25px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.wp-block-woocommerce-checkout-express-payment-block {
|
||||||
|
transition: opacity .2s ease-in,
|
||||||
|
scale .2s ease-in,
|
||||||
|
display .4s ease-in;
|
||||||
|
/* key to transitioning out */
|
||||||
|
transition-behavior: allow-discrete;
|
||||||
|
|
||||||
|
/* stage enter */
|
||||||
|
/* key to transitioning in */
|
||||||
|
@starting-style {
|
||||||
|
opacity: 0;
|
||||||
|
scale: 1.1;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.wc-block-axo-is-authenticated {
|
||||||
|
opacity: 0;
|
||||||
|
scale: .9;
|
||||||
|
|
||||||
|
/* hidden sets display: none, but loses easily */
|
||||||
|
display: none !important;
|
||||||
|
|
||||||
|
/* faster leaving the stage then entering */
|
||||||
|
transition-duration: .2s;
|
||||||
|
transition-timing-function: var(--ease-out-5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.wc-block-axo-is-loaded .wc-block-components-text-input {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wc-block-axo-is-loaded .wc-block-components-text-input {
|
||||||
|
margin-bottom: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wc-block-checkout-axo-block-watermark-container {
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wc-block-axo-is-loaded {
|
||||||
|
.wc-block-components-text-input {
|
||||||
|
display: grid;
|
||||||
|
grid-template-areas:
|
||||||
|
"input button"
|
||||||
|
"watermark watermark"
|
||||||
|
"error error";
|
||||||
|
grid-template-columns: 1fr auto;
|
||||||
|
gap: 6px 8px;
|
||||||
|
align-items: start;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.wc-block-axo-is-authenticated .wc-block-components-text-input {
|
||||||
|
gap: 14px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wc-block-components-text-input input[type="email"] {
|
||||||
|
grid-area: input;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wc-block-axo-email-submit-button-container {
|
||||||
|
grid-area: button;
|
||||||
|
align-self: start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wc-block-checkout-axo-block-watermark-container {
|
||||||
|
grid-area: watermark;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wc-block-components-validation-error {
|
||||||
|
grid-area: error;
|
||||||
|
width: 100%;
|
||||||
|
margin-top: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensure the button doesn't stretch */
|
||||||
|
.wc-block-axo-email-submit-button-container .wc-block-components-button {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Responsive adjustments */
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.wc-block-components-text-input {
|
||||||
|
grid-template-areas:
|
||||||
|
"input"
|
||||||
|
"button"
|
||||||
|
"watermark"
|
||||||
|
"error";
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,102 @@
|
||||||
|
import { createElement, createRoot } from '@wordpress/element';
|
||||||
|
import { useSelect } from '@wordpress/data';
|
||||||
|
import { STORE_NAME } from '../stores/axoStore';
|
||||||
|
|
||||||
|
const EmailSubmitButton = ( { onEmailSubmit } ) => {
|
||||||
|
const { isGuest, isAxoActive } = useSelect( ( select ) => ( {
|
||||||
|
isGuest: select( STORE_NAME ).getIsGuest(),
|
||||||
|
isAxoActive: select( STORE_NAME ).getIsAxoActive(),
|
||||||
|
} ) );
|
||||||
|
|
||||||
|
const handleSubmit = () => {
|
||||||
|
const emailInput = document.getElementById( 'email' );
|
||||||
|
if ( emailInput && emailInput.value ) {
|
||||||
|
onEmailSubmit( emailInput.value );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if ( ! isGuest || ! isAxoActive ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={ handleSubmit }
|
||||||
|
className="wc-block-components-button wp-element-button"
|
||||||
|
>
|
||||||
|
Submit
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Setup and removal functions
|
||||||
|
let submitButtonReference = {
|
||||||
|
container: null,
|
||||||
|
root: null,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const setupEmailSubmitButton = ( onEmailSubmit ) => {
|
||||||
|
const emailInput = document.getElementById( 'email' );
|
||||||
|
|
||||||
|
if ( emailInput ) {
|
||||||
|
if ( ! submitButtonReference.container ) {
|
||||||
|
submitButtonReference.container = document.createElement( 'div' );
|
||||||
|
submitButtonReference.container.setAttribute(
|
||||||
|
'class',
|
||||||
|
'wc-block-axo-email-submit-button-container'
|
||||||
|
);
|
||||||
|
|
||||||
|
emailInput.parentNode.insertBefore(
|
||||||
|
submitButtonReference.container,
|
||||||
|
emailInput.nextSibling
|
||||||
|
);
|
||||||
|
|
||||||
|
submitButtonReference.root = createRoot(
|
||||||
|
submitButtonReference.container
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( submitButtonReference.root ) {
|
||||||
|
const renderButton = () => {
|
||||||
|
submitButtonReference.root.render(
|
||||||
|
createElement( EmailSubmitButton, { onEmailSubmit } )
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
renderButton(); // Initial render
|
||||||
|
|
||||||
|
// Subscribe to state changes
|
||||||
|
const unsubscribe = wp.data.subscribe( () => {
|
||||||
|
renderButton();
|
||||||
|
} );
|
||||||
|
|
||||||
|
// Store the unsubscribe function for cleanup
|
||||||
|
submitButtonReference.unsubscribe = unsubscribe;
|
||||||
|
} else {
|
||||||
|
console.warn( 'Submit button root not found' );
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.warn( 'Email input not found' );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const removeEmailSubmitButton = () => {
|
||||||
|
if ( submitButtonReference.root ) {
|
||||||
|
submitButtonReference.root.unmount();
|
||||||
|
}
|
||||||
|
if ( submitButtonReference.unsubscribe ) {
|
||||||
|
submitButtonReference.unsubscribe();
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
submitButtonReference.container &&
|
||||||
|
submitButtonReference.container.parentNode
|
||||||
|
) {
|
||||||
|
submitButtonReference.container.parentNode.removeChild(
|
||||||
|
submitButtonReference.container
|
||||||
|
);
|
||||||
|
}
|
||||||
|
submitButtonReference = { container: null, root: null, unsubscribe: null };
|
||||||
|
};
|
||||||
|
|
||||||
|
export default EmailSubmitButton;
|
102
modules/ppcp-axo-block/resources/js/helpers/classnamesManager.js
Normal file
102
modules/ppcp-axo-block/resources/js/helpers/classnamesManager.js
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
import { select, subscribe } from '@wordpress/data';
|
||||||
|
import { STORE_NAME } from '../stores/axoStore';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets up a class toggle based on the isGuest state for the express payment block.
|
||||||
|
* @return {Function} Unsubscribe function for cleanup.
|
||||||
|
*/
|
||||||
|
export const setupAuthenticationClassToggle = () => {
|
||||||
|
const targetSelector =
|
||||||
|
'.wp-block-woocommerce-checkout-express-payment-block';
|
||||||
|
const authClass = 'wc-block-axo-is-authenticated';
|
||||||
|
|
||||||
|
const updateAuthenticationClass = () => {
|
||||||
|
const targetElement = document.querySelector( targetSelector );
|
||||||
|
if ( ! targetElement ) {
|
||||||
|
console.warn( `Target element not found: ${ targetSelector }` );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const isGuest = select( STORE_NAME ).getIsGuest();
|
||||||
|
|
||||||
|
if ( ! isGuest ) {
|
||||||
|
targetElement.classList.add( authClass );
|
||||||
|
} else {
|
||||||
|
targetElement.classList.remove( authClass );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Initial update
|
||||||
|
updateAuthenticationClass();
|
||||||
|
|
||||||
|
// Subscribe to state changes
|
||||||
|
const unsubscribe = subscribe( () => {
|
||||||
|
updateAuthenticationClass();
|
||||||
|
} );
|
||||||
|
|
||||||
|
// Return the unsubscribe function for cleanup
|
||||||
|
return unsubscribe;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets up class toggles for the contact information block based on isAxoActive and isGuest states.
|
||||||
|
* @return {Function} Unsubscribe function for cleanup.
|
||||||
|
*/
|
||||||
|
export const setupContactInfoClassToggles = () => {
|
||||||
|
const targetSelector =
|
||||||
|
'.wp-block-woocommerce-checkout-contact-information-block';
|
||||||
|
const axoLoadedClass = 'wc-block-axo-is-loaded';
|
||||||
|
const authClass = 'wc-block-axo-is-authenticated';
|
||||||
|
|
||||||
|
const updateContactInfoClasses = () => {
|
||||||
|
const targetElement = document.querySelector( targetSelector );
|
||||||
|
if ( ! targetElement ) {
|
||||||
|
console.warn( `Target element not found: ${ targetSelector }` );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const isAxoActive = select( STORE_NAME ).getIsAxoActive();
|
||||||
|
const isGuest = select( STORE_NAME ).getIsGuest();
|
||||||
|
|
||||||
|
if ( isAxoActive ) {
|
||||||
|
targetElement.classList.add( axoLoadedClass );
|
||||||
|
} else {
|
||||||
|
targetElement.classList.remove( axoLoadedClass );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! isGuest ) {
|
||||||
|
targetElement.classList.add( authClass );
|
||||||
|
} else {
|
||||||
|
targetElement.classList.remove( authClass );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Initial update
|
||||||
|
updateContactInfoClasses();
|
||||||
|
|
||||||
|
// Subscribe to state changes
|
||||||
|
const unsubscribe = subscribe( () => {
|
||||||
|
updateContactInfoClasses();
|
||||||
|
} );
|
||||||
|
|
||||||
|
// Return the unsubscribe function for cleanup
|
||||||
|
return unsubscribe;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes all class toggles.
|
||||||
|
* @return {Function} Cleanup function.
|
||||||
|
*/
|
||||||
|
export const initializeClassToggles = () => {
|
||||||
|
const unsubscribeAuth = setupAuthenticationClassToggle();
|
||||||
|
const unsubscribeContactInfo = setupContactInfoClassToggles();
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
if ( unsubscribeAuth ) {
|
||||||
|
unsubscribeAuth();
|
||||||
|
}
|
||||||
|
if ( unsubscribeContactInfo ) {
|
||||||
|
unsubscribeContactInfo();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
|
@ -17,50 +17,53 @@ const WatermarkManager = ( { fastlaneSdk } ) => {
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect( () => {
|
useEffect( () => {
|
||||||
const emailInput = document.getElementById( 'email' );
|
const textInputContainer = document.querySelector(
|
||||||
|
'.wp-block-woocommerce-checkout-contact-information-block .wc-block-components-text-input'
|
||||||
|
);
|
||||||
|
|
||||||
if ( emailInput ) {
|
if ( textInputContainer ) {
|
||||||
if ( ! watermarkReference.container ) {
|
const emailInput = textInputContainer.querySelector(
|
||||||
watermarkReference.container = document.createElement( 'div' );
|
'input[type="email"]'
|
||||||
watermarkReference.container.setAttribute(
|
);
|
||||||
'class',
|
|
||||||
'ppcp-axo-block-watermark-container'
|
|
||||||
);
|
|
||||||
|
|
||||||
const emailLabel =
|
if ( emailInput ) {
|
||||||
emailInput.parentNode.querySelector( 'label[for="email"]' );
|
if ( ! watermarkReference.container ) {
|
||||||
if ( emailLabel ) {
|
watermarkReference.container =
|
||||||
emailLabel.parentNode.insertBefore(
|
document.createElement( 'div' );
|
||||||
watermarkReference.container,
|
watermarkReference.container.setAttribute(
|
||||||
emailLabel.nextSibling
|
'class',
|
||||||
|
'wc-block-checkout-axo-block-watermark-container'
|
||||||
);
|
);
|
||||||
} else {
|
|
||||||
|
// Insert the watermark container after the email input
|
||||||
emailInput.parentNode.insertBefore(
|
emailInput.parentNode.insertBefore(
|
||||||
watermarkReference.container,
|
watermarkReference.container,
|
||||||
emailInput.nextSibling
|
emailInput.nextSibling
|
||||||
);
|
);
|
||||||
|
|
||||||
|
watermarkReference.root = createRoot(
|
||||||
|
watermarkReference.container
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
watermarkReference.root = createRoot(
|
if ( watermarkReference.root && isAxoActive ) {
|
||||||
watermarkReference.container
|
watermarkReference.root.render(
|
||||||
);
|
createElement( FastlaneWatermark, {
|
||||||
}
|
fastlaneSdk,
|
||||||
|
name: 'fastlane-watermark-email',
|
||||||
if ( watermarkReference.root && isAxoActive ) {
|
includeAdditionalInfo: isGuest,
|
||||||
watermarkReference.root.render(
|
} )
|
||||||
createElement( FastlaneWatermark, {
|
);
|
||||||
fastlaneSdk,
|
} else if ( ! isAxoActive && watermarkReference.root ) {
|
||||||
name: 'fastlane-watermark-email',
|
watermarkReference.root.render( null );
|
||||||
includeAdditionalInfo: isGuest,
|
}
|
||||||
} )
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
console.warn( 'Watermark root not found' );
|
console.warn( 'Email input not found' );
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.warn( 'Email input not found' );
|
console.warn( 'Text input container not found' );
|
||||||
}
|
}
|
||||||
}, [ fastlaneSdk, isGuest ] );
|
}, [ fastlaneSdk, isGuest, isAxoActive ] );
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
|
@ -21,6 +21,7 @@ import { snapshotFields, restoreOriginalFields } from './helpers/fieldHelpers';
|
||||||
import { removeWatermark, setupWatermark } from './helpers/watermarkHelpers';
|
import { removeWatermark, setupWatermark } from './helpers/watermarkHelpers';
|
||||||
import { removeCardChangeButton } from './helpers/cardChangeButtonManager';
|
import { removeCardChangeButton } from './helpers/cardChangeButtonManager';
|
||||||
import { removeShippingChangeButton } from './helpers/shippingChangeButtonManager';
|
import { removeShippingChangeButton } from './helpers/shippingChangeButtonManager';
|
||||||
|
import { initializeClassToggles } from './helpers/classnamesManager';
|
||||||
|
|
||||||
// Stores
|
// Stores
|
||||||
import { STORE_NAME } from './stores/axoStore';
|
import { STORE_NAME } from './stores/axoStore';
|
||||||
|
@ -32,6 +33,7 @@ import {
|
||||||
removeEmailEvent,
|
removeEmailEvent,
|
||||||
isEmailEventSetup,
|
isEmailEventSetup,
|
||||||
} from './helpers/emailHelpers';
|
} from './helpers/emailHelpers';
|
||||||
|
import { setupEmailSubmitButton } from './components/EmailSubmitButton';
|
||||||
|
|
||||||
const ppcpConfig = wc.wcSettings.getSetting( 'ppcp-credit-card-gateway_data' );
|
const ppcpConfig = wc.wcSettings.getSetting( 'ppcp-credit-card-gateway_data' );
|
||||||
|
|
||||||
|
@ -66,6 +68,10 @@ const Axo = () => {
|
||||||
console.log( 'isAxoActive updated:', isAxoActive );
|
console.log( 'isAxoActive updated:', isAxoActive );
|
||||||
}, [ isAxoActive ] );
|
}, [ isAxoActive ] );
|
||||||
|
|
||||||
|
useEffect( () => {
|
||||||
|
initializeClassToggles();
|
||||||
|
}, [] );
|
||||||
|
|
||||||
useEffect( () => {
|
useEffect( () => {
|
||||||
return () => {
|
return () => {
|
||||||
// Restore WooCommerce fields
|
// Restore WooCommerce fields
|
||||||
|
@ -141,6 +147,9 @@ const Axo = () => {
|
||||||
console.log( 'Enabling Axo' );
|
console.log( 'Enabling Axo' );
|
||||||
setIsAxoActive( true );
|
setIsAxoActive( true );
|
||||||
setupWatermark( fastlaneSdk );
|
setupWatermark( fastlaneSdk );
|
||||||
|
setupEmailSubmitButton( async ( email ) => {
|
||||||
|
await onEmailSubmit( email );
|
||||||
|
} );
|
||||||
setupEmailEvent( handleEmailInputRef.current );
|
setupEmailEvent( handleEmailInputRef.current );
|
||||||
}
|
}
|
||||||
}, [ paypalLoaded, fastlaneSdk, setIsAxoActive ] );
|
}, [ paypalLoaded, fastlaneSdk, setIsAxoActive ] );
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue