-
Notifications
You must be signed in to change notification settings - Fork 69
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Reporting: Show bank reference ID on Payout details page #9945
base: develop
Are you sure you want to change the base?
Conversation
Test the buildOption 1. Jetpack Beta
Option 2. Jurassic Ninja - available for logged-in A12s🚀 Launch a JN site with this branch 🚀 ℹ️ Install this Tampermonkey script to get more options. Build info:
Note: the build is updated when a new commit is pushed to this PR. |
Size Change: +1.35 kB (0%) Total Size: 1.39 MB
ℹ️ View Unchanged
|
export const CopyButton: React.FC< CopyButtonProps > = ( { | ||
textToCopy, | ||
label, | ||
} ) => { | ||
// useRef() is used to store the timer reference for the setTimeout() function. | ||
const timerRef = useRef< NodeJS.Timeout | null >( null ); | ||
|
||
// useEffect() is used to clear the timer reference when the component is unmounted. | ||
useEffect( () => { | ||
return () => { | ||
if ( timerRef.current ) { | ||
clearTimeout( timerRef.current ); | ||
} | ||
}; | ||
}, [] ); | ||
|
||
const [ copied, setCopied ] = useState( false ); | ||
|
||
const copyToClipboard = () => { | ||
navigator.clipboard.writeText( textToCopy ); | ||
setCopied( true ); | ||
timerRef.current = setTimeout( () => { | ||
setCopied( false ); | ||
}, 2000 ); | ||
}; | ||
|
||
return ( | ||
<button | ||
type="button" | ||
className={ classNames( 'woopayments-copy-button', { | ||
'state--copied': copied, | ||
} ) } | ||
aria-label={ label } | ||
title={ __( 'Copy to clipboard', 'woocommerce-payments' ) } | ||
onClick={ copyToClipboard } | ||
> | ||
<i></i> | ||
</button> | ||
); | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work implementing this tricky bit of logic. Using the setTimeout
and cleaning up in the useEffect
return works well 🙌
I had a thought while looking at this, though – our intention with to show → 2s → hide
a CSS change might be better served by a CSS animation. Since CSS animations already have "timer" logic, we can rely on it rather than implement a custom timer, whilst using React state to add and remove the classname.
The onAnimationEnd
event handler will also abort if the element is unmounted, so we don't need to handle any cleanup of any timers.
Let me know what you think – I think it is a tidier and less complex approach (less code to understand and maintain), but there are tradeoffs. E.g. it might be less obvious to code readers where the timer is originating from (CSS, rather than JS).
export const CopyButton: React.FC< CopyButtonProps > = ( {
textToCopy,
label,
} ) => {
- // useRef() is used to store the timer reference for the setTimeout() function.
- const timerRef = useRef< NodeJS.Timeout | null >( null );
-
- // useEffect() is used to clear the timer reference when the component is unmounted.
- useEffect( () => {
- return () => {
- if ( timerRef.current ) {
- clearTimeout( timerRef.current );
- }
- };
- }, [] );
-
const [ copied, setCopied ] = useState( false );
const copyToClipboard = () => {
navigator.clipboard.writeText( textToCopy );
setCopied( true );
- timerRef.current = setTimeout( () => {
- setCopied( false );
- }, 2000 );
};
return (
<button
type="button"
className={ classNames( 'woopayments-copy-button', {
'state--copied': copied,
} ) }
aria-label={ label }
title={ __( 'Copy to clipboard', 'woocommerce-payments' ) }
onClick={ copyToClipboard }
+ onAnimationEnd={ () => setCopied( false ) }
>
<i></i>
</button>
);
And then in the CSS:
&.state--copied {
animation: copy-indicator 2s forwards;
}
@keyframes copy-indicator {
0% {
opacity: 1;
}
95% {
opacity: 1;
}
// a quick fade-out from 1%→0% at the end
100% {
opacity: 0;
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The CSS suggestion is brilliant. I would prefer using CSS to additional JS/ React script. It is much cleaner and easier to maintain. I will try this out and update. Thanks so much!
expect( button ).toHaveClass( 'state--copied' ); | ||
|
||
act( () => { | ||
jest.advanceTimersByTime( 2000 ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, so it seems that the jest JSDOM env won't be running CSS animations, but this can be manually triggered using fireEvent
:
jest.advanceTimersByTime( 2000 ); | |
fireEvent.animationEnd( button ); |
Then we also won't need to override the jest timer setup and teardown.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks Eric!
…out-details-header
Fixes #9878
Changes proposed in this Pull Request
Current status
Awaiting some guidance from design on responsive behavior of the additional header component.
The component currently renders like this:
Testing instructions
npm run changelog
to add a changelog file, choosepatch
to leave it empty if the change is not significant. You can add multiple changelog files in one PR by running this command a few times.Post merge