mirror of
https://github.com/woocommerce/woocommerce-paypal-payments.git
synced 2025-09-04 08:47:23 +08:00
💄 Fix multiple spinners in nested Busy-wrappers
This commit is contained in:
parent
1826b95c08
commit
70e2015e1f
3 changed files with 30 additions and 14 deletions
|
@ -12,5 +12,6 @@
|
||||||
top: 50%;
|
top: 50%;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
transform: translate(-50%, -50%);
|
transform: translate(-50%, -50%);
|
||||||
|
margin: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,34 +3,43 @@ import {
|
||||||
isValidElement,
|
isValidElement,
|
||||||
cloneElement,
|
cloneElement,
|
||||||
useMemo,
|
useMemo,
|
||||||
|
createContext,
|
||||||
|
useContext,
|
||||||
} from '@wordpress/element';
|
} from '@wordpress/element';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
|
||||||
import { CommonHooks } from '../../data';
|
import { CommonHooks } from '../../data';
|
||||||
import SpinnerOverlay from './SpinnerOverlay';
|
import SpinnerOverlay from './SpinnerOverlay';
|
||||||
|
|
||||||
|
// Create context to track the busy state across nested wrappers
|
||||||
|
const BusyContext = createContext( false );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wraps interactive child elements and modifies their behavior based on the global `isBusy` state.
|
* Wraps interactive child elements and modifies their behavior based on the global `isBusy` state.
|
||||||
* Allows custom processing of child props via the `onBusy` callback.
|
* Allows custom processing of child props via the `onBusy` callback.
|
||||||
*
|
*
|
||||||
* @param {Object} props - Component properties.
|
* @param {Object} props - Component properties.
|
||||||
* @param {Children} props.children - Child components to wrap.
|
* @param {Children} props.children - Child components to wrap.
|
||||||
* @param {boolean} props.enabled - Enables or disables the busy-state logic.
|
* @param {boolean} props.enabled - Enables or disables the busy-state logic.
|
||||||
* @param {string} props.className - Additional class names for the wrapper.
|
* @param {boolean} props.busySpinner - Allows disabling the spinner in busy-state.
|
||||||
* @param {Function} props.onBusy - Callback to process child props when busy.
|
* @param {string} props.className - Additional class names for the wrapper.
|
||||||
|
* @param {Function} props.onBusy - Callback to process child props when busy.
|
||||||
*/
|
*/
|
||||||
const BusyStateWrapper = ( {
|
const BusyStateWrapper = ( {
|
||||||
children,
|
children,
|
||||||
enabled = true,
|
enabled = true,
|
||||||
|
busySpinner = true,
|
||||||
className = '',
|
className = '',
|
||||||
onBusy = () => ( { disabled: true } ),
|
onBusy = () => ( { disabled: true } ),
|
||||||
} ) => {
|
} ) => {
|
||||||
const { isBusy } = CommonHooks.useBusyState();
|
const { isBusy } = CommonHooks.useBusyState();
|
||||||
|
const hasBusyParent = useContext( BusyContext );
|
||||||
|
|
||||||
const markAsBusy = isBusy && enabled;
|
const isBusyComponent = isBusy && enabled;
|
||||||
|
const showSpinner = busySpinner && isBusyComponent && ! hasBusyParent;
|
||||||
|
|
||||||
const wrapperClassName = classNames( 'ppcp-r-busy-wrapper', className, {
|
const wrapperClassName = classNames( 'ppcp-r-busy-wrapper', className, {
|
||||||
'ppcp--is-loading': markAsBusy,
|
'ppcp--is-loading': isBusyComponent,
|
||||||
} );
|
} );
|
||||||
|
|
||||||
const memoizedChildren = useMemo(
|
const memoizedChildren = useMemo(
|
||||||
|
@ -39,18 +48,20 @@ const BusyStateWrapper = ( {
|
||||||
isValidElement( child )
|
isValidElement( child )
|
||||||
? cloneElement(
|
? cloneElement(
|
||||||
child,
|
child,
|
||||||
markAsBusy ? onBusy( child.props ) : {}
|
isBusyComponent ? onBusy( child.props ) : {}
|
||||||
)
|
)
|
||||||
: child
|
: child
|
||||||
),
|
),
|
||||||
[ children, markAsBusy, onBusy ]
|
[ children, isBusyComponent, onBusy ]
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={ wrapperClassName }>
|
<BusyContext.Provider value={ isBusyComponent }>
|
||||||
{ markAsBusy && <SpinnerOverlay /> }
|
<div className={ wrapperClassName }>
|
||||||
{ memoizedChildren }
|
{ showSpinner && <SpinnerOverlay /> }
|
||||||
</div>
|
{ memoizedChildren }
|
||||||
|
</div>
|
||||||
|
</BusyContext.Provider>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@ const Navigation = ( { stepDetails, onNext, onPrev, onExit } ) => {
|
||||||
<div className="ppcp-r-navigation">
|
<div className="ppcp-r-navigation">
|
||||||
<BusyStateWrapper
|
<BusyStateWrapper
|
||||||
className="ppcp-r-navigation--left"
|
className="ppcp-r-navigation--left"
|
||||||
|
busySpinner={ false }
|
||||||
enabled={ ! isFirst }
|
enabled={ ! isFirst }
|
||||||
>
|
>
|
||||||
<Button
|
<Button
|
||||||
|
@ -46,7 +47,10 @@ const Navigation = ( { stepDetails, onNext, onPrev, onExit } ) => {
|
||||||
|
|
||||||
const NextButton = ( { showNext, isDisabled, onNext, onExit } ) => {
|
const NextButton = ( { showNext, isDisabled, onNext, onExit } ) => {
|
||||||
return (
|
return (
|
||||||
<BusyStateWrapper className="ppcp-r-navigation--right">
|
<BusyStateWrapper
|
||||||
|
className="ppcp-r-navigation--right"
|
||||||
|
busySpinner={ false }
|
||||||
|
>
|
||||||
<Button variant="link" onClick={ onExit }>
|
<Button variant="link" onClick={ onExit }>
|
||||||
{ __( 'Save and exit', 'woocommerce-paypal-payments' ) }
|
{ __( 'Save and exit', 'woocommerce-paypal-payments' ) }
|
||||||
</Button>
|
</Button>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue