diff --git a/src/app/pages/ArticlePage/ArticlePage.styles.ts b/src/app/pages/ArticlePage/ArticlePage.styles.ts
index 784d53d8fb3..8783aad40c6 100644
--- a/src/app/pages/ArticlePage/ArticlePage.styles.ts
+++ b/src/app/pages/ArticlePage/ArticlePage.styles.ts
@@ -243,4 +243,14 @@ export default {
padding: 0,
},
}),
+ mobileOJContainer: ({ mq }: Theme) =>
+ css({
+ [mq.GROUP_4_MIN_WIDTH]: {
+ display: 'none',
+ },
+ }),
+ midArticleOJ: () =>
+ css({
+ marginBottom: `${pixelsToRem(40)}rem`,
+ }),
};
diff --git a/src/app/pages/ArticlePage/ArticlePage.tsx b/src/app/pages/ArticlePage/ArticlePage.tsx
index e66dce0d0e5..c4366ce8e49 100644
--- a/src/app/pages/ArticlePage/ArticlePage.tsx
+++ b/src/app/pages/ArticlePage/ArticlePage.tsx
@@ -1,4 +1,4 @@
-import { use, useState, useCallback } from 'react';
+import { Fragment, ReactNode, useState, useCallback, use } from 'react';
import { useTheme } from '@emotion/react';
import useToggle from '#hooks/useToggle';
import useMediaQuery from '#hooks/useMediaQuery';
@@ -59,6 +59,7 @@ import ContinueReadingButton, {
ContinueReadingButtonProps,
} from '#app/components/ContinueReadingButton';
import SaveArticleButton from '#app/components/SaveArticleButton';
+import FeaturesAnalysis from '#containers/CpsFeaturesAnalysis';
import AccountPromotionalBannerExperiment from '#app/components/Account/AccountPromotionalBannerExperiment';
import ElectionBanner from './ElectionBanner';
import ArticleMessageBanner from './ArticleMessageBanner';
@@ -84,6 +85,9 @@ import RelatedContentSection from '../../components/RelatedContentSection';
import TopicDiscovery from '../../components/TopicDiscovery';
import Disclaimer from '../../components/Disclaimer';
import SecondaryColumn from './SecondaryColumn';
+import useMobileOJComponentOrder, {
+ useDebugVariant,
+} from './useMobileOJComponentOrder';
import styles from './ArticlePage.styles';
import { ComponentToRenderProps, TimeStampProps } from './types';
import ArticleHeadline from './ArticleHeadline';
@@ -92,6 +96,12 @@ import {
isPortraitVideoUnderHeadline,
} from '../../components/MediaLoader/utils/isPortraitVideo';
import LocationBasedTopicOJ from '../../components/LocationBasedTopicOJ';
+import {
+ OJComponentKey,
+ SEARCH_MID_ARTICLE_COMPONENT,
+ SearchVariant,
+} from './searchReferrerComponentOrder';
+import TopStoriesSection from './PagePromoSections/TopStoriesSection';
const getImageComponent =
(preloadLeadImageToggle: boolean) => (props: ComponentToRenderProps) => (
@@ -161,6 +171,7 @@ const getWsojComponent = ({
}) => (
);
+
const DisclaimerWithPaddingOverride = (props: ComponentToRenderProps) => (
);
@@ -292,6 +303,60 @@ const ArticlePage = ({ pageData }: { pageData: Article }) => {
?.split(':')
?.includes('topcat');
+ const showCountryCuration = Boolean(
+ !isAmp &&
+ !isLite &&
+ !isApp &&
+ countryCurationEnabled &&
+ pageData?.countryCuration?.summaries?.length,
+ );
+
+ const hasRelatedContent = blocks.some(
+ block => block.type === 'relatedContent',
+ );
+
+ const getSearchMidArticleOJ = ({
+ data,
+ experimentProps,
+ searchVariant,
+ }: {
+ data: Recommendation[];
+ experimentProps?: ComponentExperimentProps | null;
+ searchVariant: SearchVariant | null;
+ }) => {
+ const midarticleOJ = searchVariant
+ ? SEARCH_MID_ARTICLE_COMPONENT[searchVariant]
+ : null;
+ switch (midarticleOJ) {
+ case 'mostRead':
+ return ;
+
+ case 'relatedContent':
+ return hasRelatedContent ? (
+
+
+
+ ) : (
+
+ );
+
+ case 'topicDiscovery':
+ return ;
+
+ case 'locationBasedOJ':
+ return showCountryCuration ? (
+
+
+
+ ) : (
+
+ );
+
+ default:
+ return getWsojComponent({ data, experimentProps });
+ }
+ };
+
const showPortraitVideoCarousel = Boolean(
pageData?.portraitVideoItems?.portraitVideo?.blocks?.length &&
articlePortraitVideoEnabled,
@@ -350,6 +415,9 @@ const ArticlePage = ({ pageData }: { pageData: Article }) => {
promoImageRawBlock?.model as { locator?: string } | undefined
)?.locator;
+ const searchVariant = useDebugVariant();
+ const mobileOJOrder = useMobileOJComponentOrder(searchVariant);
+
const componentsToRender = {
visuallyHiddenHeadline,
headline: getHeadlineComponent,
@@ -376,10 +444,11 @@ const ArticlePage = ({ pageData }: { pageData: Article }) => {
group: gist,
links: ArticleLinksBlock,
mpu: getMpuComponent(allowAdvertising),
+ // renders wsoj if user is on desktop, otherwise renders a chosen OJ based on search referrer experiment on mobile
wsoj: ({ data }: { data: Recommendation[] }) =>
- getWsojComponent({
- data,
- }),
+ !isDesktopViewport
+ ? getSearchMidArticleOJ({ data, searchVariant })
+ : getWsojComponent({ data }),
disclaimer: DisclaimerWithPaddingOverride,
podcastPromo: getPodcastPromoComponent(podcastPromoEnabled),
...(showContinueReadingButton && {
@@ -404,8 +473,16 @@ const ArticlePage = ({ pageData }: { pageData: Article }) => {
const showTopicDiscovery = topicDiscoveryEnabled && !isAmp && !isLite;
+ // Topic Discovery shows in the midarticle position for one variant
+ // We want to hide RelatedTopics when this happens
+ const topicDiscoveryInMidArticlePosition =
+ !isDesktopViewport && searchVariant === 'variant_5_recommended_mid';
+
const showRelatedTopicsComponent = Boolean(
- showRelatedTopics && topics.length > 0 && !showTopicDiscovery,
+ showRelatedTopics &&
+ topics.length > 0 &&
+ !showTopicDiscovery &&
+ !topicDiscoveryInMidArticlePosition,
);
const showMediaCuration = Boolean(
@@ -417,13 +494,112 @@ const ArticlePage = ({ pageData }: { pageData: Article }) => {
articleVideoCurationEnabled,
);
- const showCountryCuration = Boolean(
- !isAmp &&
- !isLite &&
- !isApp &&
- countryCurationEnabled &&
- pageData?.countryCuration?.summaries?.length,
- );
+ const topStoriesContent = pageData?.secondaryColumn?.topStories;
+ const featuresContent = pageData?.secondaryColumn?.features;
+
+ const getTopicDiscoverySlot = () => {
+ if (showTopicDiscovery) {
+ return (
+
+ );
+ }
+ if (showRelatedTopicsComponent) {
+ return (
+
+ );
+ }
+ return null;
+ };
+
+ const topicDiscoverySlot = getTopicDiscoverySlot();
+
+ const getVideoOJComponent = (): ReactNode => {
+ if (showPortraitVideoCarousel) {
+ return (
+
+ );
+ }
+ if (showMediaCuration) {
+ return (
+
+ );
+ }
+ return null;
+ };
+
+ const mobileOJComponents: Record = {
+ mostRead:
+ !isApp && !isPGL ? (
+
+ ) : null,
+ topicDiscovery: topicDiscoverySlot,
+ relatedContent: ,
+ videoOJ: getVideoOJComponent(),
+ topStories:
+ !isApp && !isPGL && topStoriesContent ? (
+
+
+
+ ) : null,
+ featuredArticles:
+ !isApp && !isPGL && featuresContent ? (
+
+
+
+ ) : null,
+ locationBasedOJ: showCountryCuration ? (
+
+ ) : null,
+ };
const shouldApplyCollapsedArticleSpacing =
showContinueReadingButton && !showAllContent;
@@ -500,7 +676,7 @@ const ArticlePage = ({ pageData }: { pageData: Article }) => {
- {showTopicDiscovery && (
+ {!mobileOJOrder && showTopicDiscovery && (
{
topics={topics}
/>
)}
- {showRelatedTopicsComponent && (
+ {!mobileOJOrder && showRelatedTopicsComponent && (
{
mobileDivider={false}
/>
)}
- {showCountryCuration && }
- {showPortraitVideoCarousel && (
+ {!mobileOJOrder && showCountryCuration && (
+
+ )}
+ {!mobileOJOrder && showPortraitVideoCarousel && (
)}
-
- {showMediaCuration && (
+ {!mobileOJOrder && }
+ {!mobileOJOrder && showMediaCuration && (
{
)}
- {!isApp && !isPGL &&
}
+ {!isApp && !isPGL && !mobileOJOrder && (
+
+ )}
- {!isApp && !isPGL && (
+ {mobileOJOrder && (
+
+ {mobileOJOrder.map(key => (
+ {mobileOJComponents[key]}
+ ))}
+
+ )}
+
+ {!isApp && !isPGL && !mobileOJOrder && (
{
+ const ChartbeatAnalytics = () => null;
+ return ChartbeatAnalytics;
+});
+jest.mock('#app/components/ATIAnalytics', () => {
+ const ATIAnalytics = () => null;
+ return ATIAnalytics;
+});
+
+/* eslint-disable global-require, @typescript-eslint/no-var-requires */
+jest.mock(
+ '#app/components/MostRead',
+ () => () =>
+ require('react').createElement('div', { 'data-testid': 'most-read' }),
+);
+jest.mock(
+ '#app/components/TopicDiscovery',
+ () => () =>
+ require('react').createElement('div', { 'data-testid': 'topic-discovery' }),
+);
+jest.mock(
+ '#app/components/RelatedContentSection',
+ () => () =>
+ require('react').createElement('div', { 'data-testid': 'related-content' }),
+);
+jest.mock(
+ '#app/components/PortraitVideoCarousel',
+ () => () =>
+ require('react').createElement('div', {
+ 'data-testid': 'portrait-video-carousel',
+ }),
+);
+jest.mock(
+ '#app/components/LocationBasedTopicOJ',
+ () => () =>
+ require('react').createElement('div', {
+ 'data-testid': 'location-based-topic-oj',
+ }),
+);
+/* eslint-enable global-require, @typescript-eslint/no-var-requires */
+
+jest.mock('#app/components/OptimizelyPageMetrics');
+jest.mock('#app/hooks/useScrollDepthTracker', () => jest.fn(() => null));
+jest.mock('#hooks/useMediaQuery', () => jest.fn());
+jest.mock('#app/hooks/useOptimizelyVariation', () => ({
+ __esModule: true,
+ ...jest.requireActual('#app/hooks/useOptimizelyVariation'),
+ default: jest.fn(),
+}));
+jest.mock(
+ '#app/legacy/containers/PageHandlers/withOptimizelyProvider/userAttributes',
+);
+jest.mock('#app/lib/utilities/onClient', () => ({
+ __esModule: true,
+ default: jest.fn(),
+ onClient: jest.fn(() => true),
+}));
+
+const mockOnClient = onClient as jest.MockedFunction;
+
+describe('useMobileOJComponentOrder', () => {
+ let matchMediaMock: jest.Mock;
+
+ beforeEach(() => {
+ jest.clearAllMocks();
+ mockOnClient.mockReturnValue(true);
+
+ // Mock window.matchMedia
+ matchMediaMock = jest.fn().mockReturnValue({
+ matches: false,
+ addEventListener: jest.fn(),
+ removeEventListener: jest.fn(),
+ });
+
+ Object.defineProperty(window, 'matchMedia', {
+ writable: true,
+ value: matchMediaMock,
+ });
+ });
+
+ afterEach(() => {
+ jest.restoreAllMocks();
+ });
+
+ describe('Desktop behavior', () => {
+ it('should return null regardless of variant when on desktop', () => {
+ matchMediaMock.mockReturnValue({
+ matches: false,
+ addEventListener: jest.fn(),
+ removeEventListener: jest.fn(),
+ });
+
+ const { result: variant2Result } = renderHook(() =>
+ useMobileOJComponentOrder('variant_2_recommended'),
+ );
+ expect(variant2Result.current).toBeNull();
+
+ const { result: variant3Result } = renderHook(() =>
+ useMobileOJComponentOrder('variant_3_hybrid'),
+ );
+ expect(variant3Result.current).toBeNull();
+ });
+ });
+
+ describe('Mobile behavior with different variants', () => {
+ beforeEach(() => {
+ matchMediaMock.mockReturnValue({
+ matches: true,
+ addEventListener: jest.fn(),
+ removeEventListener: jest.fn(),
+ });
+ });
+ it.each([
+ 'variant_1_related',
+ 'variant_2_recommended',
+ 'variant_3_hybrid',
+ 'variant_4_related_mid',
+ 'variant_5_recommended_mid',
+ 'variant_6_hybrid_mid',
+ ] as SearchVariant[])('returns the correct order for %s', searchVariant => {
+ const { result } = renderHook(() =>
+ useMobileOJComponentOrder(searchVariant),
+ );
+
+ expect(result.current).toEqual(SEARCH_COMPONENT_ORDER[searchVariant]);
+ });
+ it('returns null when no variant is provided', () => {
+ const { result } = renderHook(() => useMobileOJComponentOrder(null));
+ expect(result.current).toBeNull();
+ });
+
+ describe('Renderered mobile OJ components', () => {
+ beforeEach(() => {
+ matchMediaMock.mockReturnValue({
+ matches: true,
+ addEventListener: jest.fn(),
+ removeEventListener: jest.fn(),
+ });
+ });
+
+ const OJ_TEST_IDS: Record = {
+ mostRead: 'most-read',
+ topicDiscovery: 'topic-discovery',
+ videoOJ: 'portrait-video-carousel',
+ relatedContent: 'related-content',
+ topStories: 'top-stories',
+ featuredArticles: 'features',
+ locationBasedOJ: 'location-based-topic-oj',
+ };
+
+ const renderVariant = (variant: SearchVariant) => {
+ window.history.replaceState(null, '', `?debugVariant=${variant}`);
+
+ const pageData = {
+ ...articleDataNews,
+ countryCuration: { summaries: [{ title: 'Country' }] },
+ portraitVideoItems: { portraitVideo: { blocks: [{}] } },
+ secondaryColumn: { topStories: [], features: [] },
+ } as unknown as Article;
+
+ return render(createElement(ArticlePage, { pageData }), {
+ service: 'news',
+ toggles: {
+ topicDiscovery: { enabled: true },
+ articlePortraitVideo: { enabled: true },
+ locationTopicCuration: { enabled: true },
+ },
+ });
+ };
+
+ afterEach(() => {
+ window.history.replaceState(null, '', '/');
+ });
+
+ const getRenderedOJOrder = (container: HTMLElement) => {
+ const ojTestIds = Object.values(OJ_TEST_IDS);
+ return Array.from(container.querySelectorAll('[data-testid]'))
+ .map(element => element.getAttribute('data-testid'))
+ .filter(testId => ojTestIds.includes(testId as string));
+ };
+
+ it.each([
+ 'variant_1_related',
+ 'variant_2_recommended',
+ 'variant_3_hybrid',
+ 'variant_4_related_mid',
+ 'variant_5_recommended_mid',
+ 'variant_6_hybrid_mid',
+ ] as SearchVariant[])(
+ 'renders the OJ components in the configured order for %s',
+ async searchVariant => {
+ renderVariant(searchVariant);
+
+ const container = await screen.findByTestId('mobile-oj-container');
+
+ const expectedOrder = SEARCH_COMPONENT_ORDER[searchVariant].map(
+ key => OJ_TEST_IDS[key],
+ );
+
+ expect(getRenderedOJOrder(container)).toEqual(expectedOrder);
+ },
+ );
+ });
+ });
+
+ describe('Mid-article component ordering', () => {
+ it.each([
+ ['variant_1_related', 'mostRead'],
+ ['variant_2_recommended', 'mostRead'],
+ ['variant_3_hybrid', 'mostRead'],
+ ['variant_4_related_mid', 'relatedContent'],
+ ['variant_5_recommended_mid', 'topicDiscovery'],
+ ['variant_6_hybrid_mid', 'locationBasedOJ'],
+ ] as const)('%o returns %o', (searchVariant, expectedComponent) => {
+ expect(SEARCH_MID_ARTICLE_COMPONENT[searchVariant]).toBe(
+ expectedComponent,
+ );
+ });
+ });
+
+ describe('Media query listener', () => {
+ it('should add a change listener to media query on client', () => {
+ const addEventListenerMock = jest.fn();
+ matchMediaMock.mockReturnValue({
+ matches: false,
+ addEventListener: addEventListenerMock,
+ removeEventListener: jest.fn(),
+ });
+
+ renderHook(() => useMobileOJComponentOrder(null));
+
+ expect(addEventListenerMock).toHaveBeenCalledWith(
+ 'change',
+ expect.any(Function),
+ );
+ });
+
+ it('should remove listener on unmount', () => {
+ const removeEventListenerMock = jest.fn();
+ matchMediaMock.mockReturnValue({
+ matches: false,
+ addEventListener: jest.fn(),
+ removeEventListener: removeEventListenerMock,
+ });
+
+ const { unmount } = renderHook(() => useMobileOJComponentOrder(null));
+
+ unmount();
+
+ expect(removeEventListenerMock).toHaveBeenCalledWith(
+ 'change',
+ expect.any(Function),
+ );
+ });
+
+ it('should update order when viewport changes from desktop to mobile', async () => {
+ let listenerCallback: ((e: MediaQueryListEvent) => void) | null = null;
+ matchMediaMock.mockImplementation(() => ({
+ matches: false,
+ addEventListener: jest.fn((event, callback) => {
+ if (event === 'change') {
+ listenerCallback = callback;
+ }
+ }),
+ removeEventListener: jest.fn(),
+ }));
+
+ const { result } = renderHook(() =>
+ useMobileOJComponentOrder('variant_1_related'),
+ );
+
+ expect(result.current).toBeNull();
+
+ if (listenerCallback) {
+ await act(async () => {
+ listenerCallback?.({
+ matches: true,
+ } as MediaQueryListEvent);
+ });
+ }
+
+ await waitFor(() => {
+ expect(result.current).not.toBeNull();
+ });
+
+ expect(result.current?.[0]).toBe('topicDiscovery');
+ });
+
+ it('should update order when viewport changes from mobile to desktop', async () => {
+ let listenerCallback: ((e: MediaQueryListEvent) => void) | null = null;
+ matchMediaMock.mockImplementation(() => ({
+ matches: true,
+ addEventListener: jest.fn((event, callback) => {
+ if (event === 'change') {
+ listenerCallback = callback;
+ }
+ }),
+ removeEventListener: jest.fn(),
+ }));
+
+ const { result } = renderHook(() =>
+ useMobileOJComponentOrder('variant_4_related_mid'),
+ );
+
+ expect(result.current).not.toBeNull();
+
+ if (listenerCallback) {
+ await act(async () => {
+ listenerCallback?.({
+ matches: false,
+ } as MediaQueryListEvent);
+ });
+ }
+
+ await waitFor(() => {
+ expect(result.current).toBeNull();
+ });
+ });
+ });
+
+ describe('Correct media query breakpoint', () => {
+ it('should use GROUP_3_MAX_WIDTH_BP for the breakpoint', () => {
+ mockOnClient.mockReturnValue(true);
+
+ renderHook(() => useMobileOJComponentOrder(null));
+
+ const callArgs = matchMediaMock.mock.calls[0][0];
+
+ expect(callArgs).toContain(`${GROUP_3_MAX_WIDTH_BP}rem`);
+ expect(callArgs).toContain('max-width');
+ });
+ });
+});
diff --git a/src/app/pages/ArticlePage/searchReferrerComponentOrder.ts b/src/app/pages/ArticlePage/searchReferrerComponentOrder.ts
new file mode 100644
index 00000000000..f7dae5184d5
--- /dev/null
+++ b/src/app/pages/ArticlePage/searchReferrerComponentOrder.ts
@@ -0,0 +1,86 @@
+export type OJComponentKey =
+ | 'mostRead'
+ | 'topicDiscovery'
+ | 'videoOJ'
+ | 'relatedContent'
+ | 'topStories'
+ | 'featuredArticles'
+ | 'locationBasedOJ';
+
+export type SearchVariant =
+ | 'variant_1_related'
+ | 'variant_2_recommended'
+ | 'variant_3_hybrid'
+ | 'variant_4_related_mid'
+ | 'variant_5_recommended_mid'
+ | 'variant_6_hybrid_mid';
+
+export const SEARCH_COMPONENT_ORDER: Record = {
+ variant_1_related: [
+ 'topicDiscovery',
+ 'relatedContent',
+ 'locationBasedOJ',
+ 'topStories',
+ 'featuredArticles',
+ 'videoOJ',
+ 'mostRead',
+ ],
+ variant_2_recommended: [
+ 'topicDiscovery',
+ 'mostRead',
+ 'relatedContent',
+ 'featuredArticles',
+ 'videoOJ',
+ 'topStories',
+ 'locationBasedOJ',
+ ],
+ variant_3_hybrid: [
+ 'topicDiscovery',
+ 'locationBasedOJ',
+ 'relatedContent',
+ 'mostRead',
+ 'videoOJ',
+ 'topStories',
+ 'featuredArticles',
+ ],
+ variant_4_related_mid: [
+ 'topicDiscovery',
+ 'locationBasedOJ',
+ 'topStories',
+ 'featuredArticles',
+ 'videoOJ',
+ 'mostRead',
+ ],
+ variant_5_recommended_mid: [
+ 'mostRead',
+ 'relatedContent',
+ 'featuredArticles',
+ 'videoOJ',
+ 'topStories',
+ 'locationBasedOJ',
+ ],
+ variant_6_hybrid_mid: [
+ 'topicDiscovery',
+ 'relatedContent',
+ 'mostRead',
+ 'videoOJ',
+ 'topStories',
+ 'featuredArticles',
+ ],
+};
+
+export type MidArticleOJ =
+ | 'mostRead'
+ | 'topicDiscovery'
+ | 'relatedContent'
+ | 'locationBasedOJ';
+
+export const SEARCH_MID_ARTICLE_COMPONENT: Record =
+ {
+ variant_1_related: 'mostRead',
+ variant_2_recommended: 'mostRead',
+ variant_3_hybrid: 'mostRead',
+ variant_4_related_mid: 'relatedContent',
+ variant_5_recommended_mid: 'topicDiscovery',
+ variant_6_hybrid_mid: 'locationBasedOJ',
+ };
diff --git a/src/app/pages/ArticlePage/useMobileOJComponentOrder.ts b/src/app/pages/ArticlePage/useMobileOJComponentOrder.ts
new file mode 100644
index 00000000000..bbc7a678d4e
--- /dev/null
+++ b/src/app/pages/ArticlePage/useMobileOJComponentOrder.ts
@@ -0,0 +1,70 @@
+import { useEffect, useState } from 'react';
+import onClient from '#app/lib/utilities/onClient';
+import { GROUP_3_MAX_WIDTH_BP } from '#app/components/ThemeProvider/mediaQueries';
+import {
+ OJComponentKey,
+ SEARCH_COMPONENT_ORDER,
+ SearchVariant,
+} from './searchReferrerComponentOrder';
+
+const getDebugVariant = (): SearchVariant | null => {
+ const params = new URLSearchParams(window.location.search);
+ const debugParam = params.get('debugVariant');
+ if (
+ debugParam &&
+ Object.prototype.hasOwnProperty.call(SEARCH_COMPONENT_ORDER, debugParam)
+ ) {
+ return debugParam as SearchVariant;
+ }
+ return null;
+};
+
+export const useDebugVariant = (): SearchVariant | null => {
+ const [debugVariant, setDebugVariant] = useState(null);
+
+ useEffect(() => {
+ if (!onClient()) return;
+
+ setDebugVariant(getDebugVariant());
+ }, []);
+
+ return debugVariant;
+};
+
+const useMobileOJComponentOrder = (
+ searchVariant: SearchVariant | null,
+): OJComponentKey[] | null => {
+ const [order, setOrder] = useState(null);
+
+ useEffect(() => {
+ if (!onClient()) return undefined;
+
+ const mediaQuery = window.matchMedia(
+ `(max-width: ${GROUP_3_MAX_WIDTH_BP}rem)`,
+ );
+
+ const mobileOrder = searchVariant
+ ? SEARCH_COMPONENT_ORDER[searchVariant]
+ : null;
+
+ const updateOrder = (matches: boolean) => {
+ setOrder(matches ? mobileOrder : null);
+ };
+
+ // Initial check
+ updateOrder(mediaQuery.matches);
+
+ // Listen for changes and use the event's matches value
+ const handleChange = (event: MediaQueryListEvent) => {
+ updateOrder(event.matches);
+ };
+
+ mediaQuery.addEventListener('change', handleChange);
+
+ return () => mediaQuery.removeEventListener('change', handleChange);
+ }, [searchVariant]);
+
+ return order;
+};
+
+export default useMobileOJComponentOrder;