diff --git a/plugins/woocommerce-blocks/assets/js/base/components/sidebar-layout/sidebar.tsx b/plugins/woocommerce-blocks/assets/js/base/components/sidebar-layout/sidebar.tsx
index 891cbe698cd8..1d4bcb5c9bb0 100644
--- a/plugins/woocommerce-blocks/assets/js/base/components/sidebar-layout/sidebar.tsx
+++ b/plugins/woocommerce-blocks/assets/js/base/components/sidebar-layout/sidebar.tsx
@@ -9,7 +9,7 @@ import classNames from 'classnames';
*/
import { ForwardRefProps } from './types';
-const Sidebar = forwardRef< HTMLInputElement, ForwardRefProps >(
+const Sidebar = forwardRef< HTMLDivElement, ForwardRefProps >(
( { children, className = '' }, ref ): JSX.Element => {
return (
{
+ * const [ observedRef, observedElement, viewWindow ] = useObservedViewport();
+ *
+ * return (
+ *
+ * );
+ * };
+ * ```
+ */
+export function useObservedViewport< T extends HTMLElement >(): [
+ React.Ref< T >,
+ { height: number; width: number },
+ { height: number; width: number }
+] {
+ const [ observedElement, setObservedElement ] = useState( {
+ height: 0,
+ width: 0,
+ } );
+
+ const [ viewWindow, setViewWindow ] = useState( {
+ height: 0,
+ width: 0,
+ } );
+
+ const observedRef = useRef< T >( null );
+
+ useEffect( () => {
+ if ( ! observedRef.current ) {
+ return;
+ }
+ const element = observedRef.current;
+ const resizeObserver = new ResizeObserver( ( entries ) => {
+ entries.forEach( ( entry ) => {
+ if ( entry.target === element ) {
+ const { height, width } = entry.contentRect;
+ const elementTop =
+ element.computedStyleMap().get( 'top' )?.toString() ||
+ '0';
+ setObservedElement( {
+ height: height + parseInt( elementTop, 10 ),
+ width,
+ } );
+ }
+ } );
+ } );
+
+ const intersectionObserver = new IntersectionObserver(
+ ( entries ) => {
+ entries.forEach( ( entry ) => {
+ const { height, width } = entry.boundingClientRect;
+ setObservedElement( { height, width } );
+ if ( entry.target.ownerDocument.defaultView ) {
+ setViewWindow( {
+ height: entry.target.ownerDocument.defaultView
+ ?.innerHeight,
+ width: entry.target.ownerDocument.defaultView
+ ?.innerWidth,
+ } );
+ }
+ } );
+ },
+ {
+ root: null,
+ rootMargin: '0px',
+ threshold: 1,
+ }
+ );
+
+ resizeObserver.observe( element );
+ intersectionObserver.observe( element );
+
+ return () => {
+ if ( ! element ) {
+ return;
+ }
+
+ resizeObserver.unobserve( element );
+ intersectionObserver.unobserve( element );
+ };
+ }, [] );
+ return [ observedRef, observedElement, viewWindow ];
+}
diff --git a/plugins/woocommerce-blocks/assets/js/blocks/checkout/inner-blocks/checkout-totals-block/frontend.tsx b/plugins/woocommerce-blocks/assets/js/blocks/checkout/inner-blocks/checkout-totals-block/frontend.tsx
index 726204c6cb75..045b87d429c6 100644
--- a/plugins/woocommerce-blocks/assets/js/blocks/checkout/inner-blocks/checkout-totals-block/frontend.tsx
+++ b/plugins/woocommerce-blocks/assets/js/blocks/checkout/inner-blocks/checkout-totals-block/frontend.tsx
@@ -4,7 +4,7 @@
import classnames from 'classnames';
import { Sidebar } from '@woocommerce/base-components/sidebar-layout';
import { StoreNoticesContainer } from '@woocommerce/blocks-components';
-
+import { useObservedViewport } from '@woocommerce/base-hooks';
const FrontendBlock = ( {
children,
className,
@@ -12,9 +12,15 @@ const FrontendBlock = ( {
children: JSX.Element;
className?: string;
} ): JSX.Element => {
+ const [ observedRef, observedElement, viewWindow ] =
+ useObservedViewport< HTMLDivElement >();
+ const isSticky = observedElement.height < viewWindow.height;
return (
( {
useResizeObserver: jest.fn().mockReturnValue( [ null, { width: 0 } ] ),
} ) );
+global.ResizeObserver = jest.fn().mockImplementation( () => ( {
+ observe: jest.fn(),
+ unobserve: jest.fn(),
+ disconnect: jest.fn(),
+} ) );
+
+global.IntersectionObserver = jest.fn().mockImplementation( () => ( {
+ observe: jest.fn(),
+ unobserve: jest.fn(),
+ disconnect: jest.fn(),
+} ) );
+
jest.mock( '@wordpress/element', () => {
return {
...jest.requireActual( '@wordpress/element' ),
diff --git a/plugins/woocommerce/changelog/47680-fix-only-sticky-summary-if-smaller-than-screen b/plugins/woocommerce/changelog/47680-fix-only-sticky-summary-if-smaller-than-screen
new file mode 100644
index 000000000000..0d2c9ff5f595
--- /dev/null
+++ b/plugins/woocommerce/changelog/47680-fix-only-sticky-summary-if-smaller-than-screen
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+Comment: This is a follow up to another PR not yet shipped.
+