From b447d4597048a3938d236f7a3bd16e6cc4e13ee9 Mon Sep 17 00:00:00 2001 From: Pedram Valiani Date: Tue, 7 Apr 2026 10:12:55 +0100 Subject: [PATCH 01/26] add services to config --- src/app/components/Navigation/config.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/app/components/Navigation/config.ts b/src/app/components/Navigation/config.ts index 5d91a50048f..4ab8ebea924 100644 --- a/src/app/components/Navigation/config.ts +++ b/src/app/components/Navigation/config.ts @@ -5,9 +5,13 @@ const SERVICES_WITH_NEW_NAV: Services[] = [ 'bengali', 'marathi', 'punjabi', + 'serbian', 'tamil', 'telugu', + 'ukchina', 'urdu', + 'uzbek', + 'zhongwen', ] as const; export default SERVICES_WITH_NEW_NAV; From 5eb49f54ace7d343d32f9a038bddedb7b851163b Mon Sep 17 00:00:00 2001 From: Pedram Valiani Date: Tue, 7 Apr 2026 10:14:57 +0100 Subject: [PATCH 02/26] add logic for ukchina article page support --- src/app/legacy/containers/Header/index.jsx | 27 +++++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/src/app/legacy/containers/Header/index.jsx b/src/app/legacy/containers/Header/index.jsx index f4a73e104c1..82485506e90 100644 --- a/src/app/legacy/containers/Header/index.jsx +++ b/src/app/legacy/containers/Header/index.jsx @@ -86,10 +86,15 @@ const HeaderContainer = ({ navItems, propsForTopBarOJComponent }) => { ); + const shouldUseNewNav = + SERVICES_WITH_NEW_NAV.includes(service) && + !(service === 'ukchina' && pageType !== ARTICLE_PAGE); + let shouldRenderScriptSwitch = false; if (scriptLink) { switch (true) { + case service === 'ukchina' && pageType !== ARTICLE_PAGE: case pageType === LIVE_PAGE: case service === 'uzbek' && ![ARTICLE_PAGE, HOME_PAGE, TOPIC_PAGE, ERROR_PAGE].includes(pageType): @@ -102,8 +107,10 @@ const HeaderContainer = ({ navItems, propsForTopBarOJComponent }) => { } if (isApp) return null; - - const shouldUseNewNav = SERVICES_WITH_NEW_NAV.includes(service); + const headerBrandCss = shouldUseNewNav + ? theme => + styles.headerBrand(theme, { hasScriptLink: shouldRenderScriptSwitch }) + : null; const NavigationComponent = shouldUseNewNav ? NewNavigationContainer @@ -116,8 +123,12 @@ const HeaderContainer = ({ navItems, propsForTopBarOJComponent }) => {
} - css={shouldUseNewNav ? styles.headerBrand : null} + scriptLink={ + shouldRenderScriptSwitch && ( + + ) + } + css={headerBrandCss} >
@@ -125,8 +136,12 @@ const HeaderContainer = ({ navItems, propsForTopBarOJComponent }) => {
} - css={shouldUseNewNav ? styles.headerBrand : null} + scriptLink={ + shouldRenderScriptSwitch && ( + + ) + } + css={headerBrandCss} >
From fbcac402d97ad47683705a1323bdcf039f99fe50 Mon Sep 17 00:00:00 2001 From: Pedram Valiani Date: Tue, 7 Apr 2026 10:15:27 +0100 Subject: [PATCH 03/26] new navigation styles for button --- .../components/Header/ScriptLink/index.tsx | 25 ++++++++++++++++--- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/src/app/components/Header/ScriptLink/index.tsx b/src/app/components/Header/ScriptLink/index.tsx index 65795317d54..454cd4019fc 100644 --- a/src/app/components/Header/ScriptLink/index.tsx +++ b/src/app/components/Header/ScriptLink/index.tsx @@ -1,11 +1,16 @@ import { use } from 'react'; import useToggle from '#hooks/useToggle'; import { RequestContext } from '#app/contexts/RequestContext'; +import SERVICES_WITH_NEW_NAV from '#app/components/Navigation/config'; import { ServiceContext } from '../../../contexts/ServiceContext'; import styles from './index.styles'; -const ScriptLink = () => { - const { scriptLink } = use(ServiceContext); +type Props = { + isNewNavigation?: boolean; +}; + +const ScriptLink = ({ isNewNavigation = false }: Props) => { + const { scriptLink, service } = use(ServiceContext); const { pathname, variant: currentVariant } = use(RequestContext); const { enabled: scriptLinkEnabled } = useToggle('scriptLink'); @@ -26,15 +31,27 @@ const ScriptLink = () => { pathPartsWithoutExtension[currentVariantIndex] = alternateVariant; const pathToVariant = pathPartsWithoutExtension.join('/'); + const useNewNavigationStyles = + isNewNavigation && SERVICES_WITH_NEW_NAV.includes(service); return ( + styles.link(theme, { isNewNavigation: useNewNavigationStyles }) + } href={pathToVariant} data-variant={alternateVariant} className="focusIndicatorRemove" > - {text} + + styles.container(theme, { + isNewNavigation: useNewNavigationStyles, + }) + } + > + {text} + ); }; From 92e5b98a6856854fe443fa04340287c5f2bb3c85 Mon Sep 17 00:00:00 2001 From: Pedram Valiani Date: Tue, 7 Apr 2026 10:27:23 +0100 Subject: [PATCH 04/26] add header styling css for new nav and script link specs --- .../Header/ScriptLink/index.styles.ts | 114 +++++++++++++----- 1 file changed, 81 insertions(+), 33 deletions(-) diff --git a/src/app/components/Header/ScriptLink/index.styles.ts b/src/app/components/Header/ScriptLink/index.styles.ts index 3975bc5f374..18246c9a029 100644 --- a/src/app/components/Header/ScriptLink/index.styles.ts +++ b/src/app/components/Header/ScriptLink/index.styles.ts @@ -1,38 +1,86 @@ +import pixelsToRem from '#app/utilities/pixelsToRem'; import { css, Theme } from '@emotion/react'; +const NEW_NAV_SCRIPT_LINK_HEIGHT = pixelsToRem(36); +const NEW_NAV_SCRIPT_LINK_MIN_WIDTH = pixelsToRem(34); +const NEW_NAV_SCRIPT_LINK_PADDING = pixelsToRem(6); +const NEW_NAV_SCRIPT_LINK_BORDER = pixelsToRem(1); +const NEW_NAV_SCRIPT_LINK_FOCUS_BORDER = pixelsToRem(4); + const styles = { - link: ({ fontSizes, fontVariants, palette, spacings, mq }: Theme) => - css({ - ...fontSizes.pica, - ...fontVariants.sansRegular, - display: 'inline-block', - color: palette.WHITE, - textDecoration: 'none', - height: '2.75rem', - border: `0.0625rem solid ${palette.WHITE}`, - margin: `${spacings.FULL}rem 0 ${spacings.FULL}rem ${spacings.FULL}rem`, - minWidth: '2.75rem', - textAlign: 'center', - '&:focus, &:hover': { - span: { - margin: '0', - border: `0.1875rem solid ${palette.WHITE}`, - }, - }, - [mq.GROUP_2_MIN_WIDTH]: { - lineHeight: `calc(2.25rem - ${spacings.FULL}rem)`, - }, - [mq.GROUP_1_MAX_WIDTH]: { - margin: `${spacings.FULL}rem 0 ${spacings.FULL}rem 0`, - }, - }), - container: ({ spacings }: Theme) => - css({ - marginTop: '0.1875rem', - width: '100%', - display: 'inline-block', - height: 'calc(100%)', - lineHeight: `calc(2.75rem - ${spacings.FULL}rem)`, - }), + link: ( + { fontSizes, fontVariants, palette, spacings, mq }: Theme, + { isNewNavigation = false }: { isNewNavigation?: boolean } = {}, + ) => + isNewNavigation + ? css({ + ...fontSizes.pica, + ...fontVariants.sansRegular, + position: 'relative', + display: 'inline-flex', + alignItems: 'stretch', + justifyContent: 'center', + boxSizing: 'border-box', + color: palette.WHITE, + textDecoration: 'none', + height: `${NEW_NAV_SCRIPT_LINK_HEIGHT}rem`, + minWidth: `${NEW_NAV_SCRIPT_LINK_MIN_WIDTH}rem`, + border: `${NEW_NAV_SCRIPT_LINK_BORDER}rem solid ${palette.WHITE}`, + textAlign: 'center', + whiteSpace: 'nowrap', + '&:focus::after, &:hover::after': { + content: '""', + position: 'absolute', + inset: 0, + boxSizing: 'border-box', + border: `${NEW_NAV_SCRIPT_LINK_FOCUS_BORDER}rem solid ${palette.WHITE}`, + pointerEvents: 'none', + }, + }) + : css({ + ...fontSizes.pica, + ...fontVariants.sansRegular, + display: 'inline-block', + color: palette.WHITE, + textDecoration: 'none', + height: '2.75rem', + border: `0.0625rem solid ${palette.WHITE}`, + margin: `${spacings.FULL}rem 0 ${spacings.FULL}rem ${spacings.FULL}rem`, + minWidth: '2.75rem', + textAlign: 'center', + '&:focus, &:hover': { + span: { + margin: '0', + border: `0.1875rem solid ${palette.WHITE}`, + }, + }, + [mq.GROUP_2_MIN_WIDTH]: { + lineHeight: `calc(2.25rem - ${spacings.FULL}rem)`, + }, + [mq.GROUP_1_MAX_WIDTH]: { + margin: `${spacings.FULL}rem 0 ${spacings.FULL}rem 0`, + }, + }), + container: ( + { spacings }: Theme, + { isNewNavigation = false }: { isNewNavigation?: boolean } = {}, + ) => + isNewNavigation + ? css({ + display: 'inline-flex', + alignItems: 'center', + justifyContent: 'center', + boxSizing: 'border-box', + height: '100%', + paddingInline: `${NEW_NAV_SCRIPT_LINK_PADDING}rem`, + lineHeight: 1, + }) + : css({ + marginTop: '0.1875rem', + width: '100%', + display: 'inline-block', + height: 'calc(100%)', + lineHeight: `calc(2.75rem - ${spacings.FULL}rem)`, + }), }; export default styles; From 3933214f6cfc568a668d56f5886ad76b48b7e1b7 Mon Sep 17 00:00:00 2001 From: Pedram Valiani Date: Tue, 7 Apr 2026 10:28:02 +0100 Subject: [PATCH 05/26] styling updates for script switch link --- .../legacy/containers/Header/index.styles.ts | 51 ++++++++++++++++--- 1 file changed, 43 insertions(+), 8 deletions(-) diff --git a/src/app/legacy/containers/Header/index.styles.ts b/src/app/legacy/containers/Header/index.styles.ts index 6011711be1c..718cbd3f130 100644 --- a/src/app/legacy/containers/Header/index.styles.ts +++ b/src/app/legacy/containers/Header/index.styles.ts @@ -27,7 +27,10 @@ export default { lineHeight: 0, }, }), - headerBrand: ({ mq, spacings }: Theme) => + headerBrand: ( + { mq, spacings }: Theme, + { hasScriptLink = false }: { hasScriptLink?: boolean } = {}, + ) => css({ minHeight: 'auto', height: `${pixelsToRem(MAX_NAV_ITEM_HEIGHT)}rem`, @@ -47,17 +50,49 @@ export default { height: `${pixelsToRem(MAX_NAV_ITEM_HEIGHT)}rem`, }, - svg: { - height: '1.5rem', + '& > div > a:first-of-type': { + paddingTop: `${pixelsToRem(2)}rem`, + + svg: { + height: '1.5rem', - [mq.GROUP_3_MIN_WIDTH]: { - height: '1.875rem', + [mq.GROUP_3_MIN_WIDTH]: { + height: '1.875rem', + }, }, }, - a: { - paddingTop: `${pixelsToRem(2)}rem`, - }, + ...(hasScriptLink && { + [mq.GROUP_0_MAX_WIDTH]: { + height: 'auto', + }, + '& > div': { + [mq.GROUP_1_MIN_WIDTH]: { + flexWrap: 'nowrap', + }, + }, + '& > div > a:first-of-type': { + [mq.GROUP_1_MIN_WIDTH]: { + flex: '1 1 auto', + minWidth: 0, + }, + }, + '& > div > div:last-child': { + [mq.GROUP_0_MAX_WIDTH]: { + flexBasis: '100%', + margin: `${spacings.FULL}rem 0`, + }, + [mq.GROUP_1_MIN_WIDTH]: { + display: 'flex', + alignItems: 'center', + flex: '0 0 auto', + marginInlineStart: 'auto', + }, + [mq.GROUP_3_MIN_WIDTH]: { + marginInlineEnd: `${pixelsToRem(-4)}rem`, + }, + }, + }), }), logoSvg: ({ palette }: Theme) => css({ From e120108e715bc10de0dfcbc577aedfe4091823fb Mon Sep 17 00:00:00 2001 From: Pedram Valiani Date: Tue, 7 Apr 2026 10:28:39 +0100 Subject: [PATCH 06/26] adds tests for ukchina articles (legacy) --- .../legacy/containers/Header/index.test.jsx | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/app/legacy/containers/Header/index.test.jsx b/src/app/legacy/containers/Header/index.test.jsx index 040b0cca3c5..f793e2fa8e8 100644 --- a/src/app/legacy/containers/Header/index.test.jsx +++ b/src/app/legacy/containers/Header/index.test.jsx @@ -157,6 +157,30 @@ describe(`Header`, () => { expect(container.querySelectorAll(scriptLinkSelector).length).toBe(0); }); + it('should render script link for ukchina article pages', () => { + const { container } = HeaderContainerWithContext({ + renderOptions: { + pageType: ARTICLE_PAGE, + service: 'ukchina', + variant: 'trad', + }, + }); + + expect(container.querySelectorAll(scriptLinkSelector).length).toBe(1); + }); + + it('should not render script link for ukchina home pages', () => { + const { container } = HeaderContainerWithContext({ + renderOptions: { + pageType: HOME_PAGE, + service: 'ukchina', + variant: 'trad', + }, + }); + + expect(container.querySelectorAll(scriptLinkSelector).length).toBe(0); + }); + describe('when service is uzbek', () => { describe.each(['cyr', 'lat'])('and variant is %s', variant => { const supportedUzbekPageTypes = [ From 04dfec8ac050c1d91f5199fbd5566b2ba6b4317e Mon Sep 17 00:00:00 2001 From: Pedram Valiani Date: Tue, 7 Apr 2026 16:14:06 +0100 Subject: [PATCH 07/26] fix underline header issue on brandsvg --- src/app/legacy/containers/Header/index.styles.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/legacy/containers/Header/index.styles.ts b/src/app/legacy/containers/Header/index.styles.ts index 718cbd3f130..53e6228d513 100644 --- a/src/app/legacy/containers/Header/index.styles.ts +++ b/src/app/legacy/containers/Header/index.styles.ts @@ -73,7 +73,7 @@ export default { }, '& > div > a:first-of-type': { [mq.GROUP_1_MIN_WIDTH]: { - flex: '1 1 auto', + flex: '0 1 auto', minWidth: 0, }, }, From f06ed52040f7dfe47f88f3c97724aa0692a83328 Mon Sep 17 00:00:00 2001 From: Pedram Valiani Date: Tue, 7 Apr 2026 16:22:59 +0100 Subject: [PATCH 08/26] cleanup --- .../components/Header/ScriptLink/index.styles.ts | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/src/app/components/Header/ScriptLink/index.styles.ts b/src/app/components/Header/ScriptLink/index.styles.ts index 18246c9a029..0677794a7c9 100644 --- a/src/app/components/Header/ScriptLink/index.styles.ts +++ b/src/app/components/Header/ScriptLink/index.styles.ts @@ -1,12 +1,6 @@ import pixelsToRem from '#app/utilities/pixelsToRem'; import { css, Theme } from '@emotion/react'; -const NEW_NAV_SCRIPT_LINK_HEIGHT = pixelsToRem(36); -const NEW_NAV_SCRIPT_LINK_MIN_WIDTH = pixelsToRem(34); -const NEW_NAV_SCRIPT_LINK_PADDING = pixelsToRem(6); -const NEW_NAV_SCRIPT_LINK_BORDER = pixelsToRem(1); -const NEW_NAV_SCRIPT_LINK_FOCUS_BORDER = pixelsToRem(4); - const styles = { link: ( { fontSizes, fontVariants, palette, spacings, mq }: Theme, @@ -23,9 +17,9 @@ const styles = { boxSizing: 'border-box', color: palette.WHITE, textDecoration: 'none', - height: `${NEW_NAV_SCRIPT_LINK_HEIGHT}rem`, - minWidth: `${NEW_NAV_SCRIPT_LINK_MIN_WIDTH}rem`, - border: `${NEW_NAV_SCRIPT_LINK_BORDER}rem solid ${palette.WHITE}`, + height: `${pixelsToRem(36)}rem`, + minWidth: `${pixelsToRem(34)}rem`, + border: `${pixelsToRem(1)}rem solid ${palette.WHITE}`, textAlign: 'center', whiteSpace: 'nowrap', '&:focus::after, &:hover::after': { @@ -33,7 +27,7 @@ const styles = { position: 'absolute', inset: 0, boxSizing: 'border-box', - border: `${NEW_NAV_SCRIPT_LINK_FOCUS_BORDER}rem solid ${palette.WHITE}`, + border: `${pixelsToRem(4)}rem solid ${palette.WHITE}`, pointerEvents: 'none', }, }) @@ -72,7 +66,7 @@ const styles = { justifyContent: 'center', boxSizing: 'border-box', height: '100%', - paddingInline: `${NEW_NAV_SCRIPT_LINK_PADDING}rem`, + paddingInline: `${pixelsToRem(6)}rem`, lineHeight: 1, }) : css({ From c65f2c50c1c14e95f973d63b54e428d98e2b97ae Mon Sep 17 00:00:00 2001 From: Pedram Valiani Date: Wed, 8 Apr 2026 08:11:14 +0100 Subject: [PATCH 09/26] update script switch typography font size --- src/app/components/Header/ScriptLink/index.styles.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/app/components/Header/ScriptLink/index.styles.ts b/src/app/components/Header/ScriptLink/index.styles.ts index 0677794a7c9..f954e8bb60b 100644 --- a/src/app/components/Header/ScriptLink/index.styles.ts +++ b/src/app/components/Header/ScriptLink/index.styles.ts @@ -8,8 +8,9 @@ const styles = { ) => isNewNavigation ? css({ - ...fontSizes.pica, ...fontVariants.sansRegular, + fontSize: `${pixelsToRem(15)}rem`, + lineHeight: 1, position: 'relative', display: 'inline-flex', alignItems: 'stretch', From f19d41fa0ed4eb0133f749710bae695b12f245e3 Mon Sep 17 00:00:00 2001 From: Pedram Valiani Date: Wed, 8 Apr 2026 08:11:35 +0100 Subject: [PATCH 10/26] update test and snapshots --- .../__snapshots__/index.test.tsx.snap | 75 +++++++++++++++++++ .../Header/ScriptLink/index.test.tsx | 10 +++ 2 files changed, 85 insertions(+) diff --git a/src/app/components/Header/ScriptLink/__snapshots__/index.test.tsx.snap b/src/app/components/Header/ScriptLink/__snapshots__/index.test.tsx.snap index 4c06d9a7b0b..dacbf8e6593 100644 --- a/src/app/components/Header/ScriptLink/__snapshots__/index.test.tsx.snap +++ b/src/app/components/Header/ScriptLink/__snapshots__/index.test.tsx.snap @@ -72,3 +72,78 @@ exports[`Script Link should render correctly 1`] = ` `; + +exports[`Script Link should render correctly for new navigation 1`] = ` +.emotion-0 { + font-family: Helvetica,Arial,STHeiti,华文黑体,"Microsoft YaHei",微软雅黑,SimSun,宋体; + font-style: normal; + font-weight: 400; + font-size: 0.9375rem; + line-height: 1; + position: relative; + display: -webkit-inline-box; + display: -webkit-inline-flex; + display: -ms-inline-flexbox; + display: inline-flex; + -webkit-align-items: stretch; + -webkit-box-align: stretch; + -ms-flex-align: stretch; + align-items: stretch; + -webkit-box-pack: center; + -ms-flex-pack: center; + -webkit-justify-content: center; + justify-content: center; + box-sizing: border-box; + color: #FFFFFF; + -webkit-text-decoration: none; + text-decoration: none; + height: 2.25rem; + min-width: 2.125rem; + border: 0.0625rem solid #FFFFFF; + text-align: center; + white-space: nowrap; +} + +.emotion-0:focus::after, +.emotion-0:hover::after { + content: ""; + position: absolute; + inset: 0; + box-sizing: border-box; + border: 0.25rem solid #FFFFFF; + pointer-events: none; +} + +.emotion-1 { + display: -webkit-inline-box; + display: -webkit-inline-flex; + display: -ms-inline-flexbox; + display: inline-flex; + -webkit-align-items: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -ms-flex-pack: center; + -webkit-justify-content: center; + justify-content: center; + box-sizing: border-box; + height: 100%; + padding-inline: 0.375rem; + line-height: 1; +} + + +`; diff --git a/src/app/components/Header/ScriptLink/index.test.tsx b/src/app/components/Header/ScriptLink/index.test.tsx index 6ac2235c105..6f44059b1a8 100644 --- a/src/app/components/Header/ScriptLink/index.test.tsx +++ b/src/app/components/Header/ScriptLink/index.test.tsx @@ -25,6 +25,16 @@ describe(`Script Link`, () => { expect(container).toMatchSnapshot(); }); + it('should render correctly for new navigation', () => { + const { container } = render(, { + toggles: enabledToggleState, + service: 'ukchina', + variant: 'trad', + pathname: '/ukchina/trad/articles/c0e8weny66ko', + }); + expect(container).toMatchSnapshot(); + }); + describe('assertions', () => { describe.each(['canonical', 'amp', 'lite'])('%s', platform => { it.each` From c4a6f25998c85ec02ef744d36fc765a118cfe3e4 Mon Sep 17 00:00:00 2001 From: Pedram Valiani Date: Wed, 8 Apr 2026 08:21:55 +0100 Subject: [PATCH 11/26] tighten script switch button position to more closely match design at group 0 --- src/app/legacy/containers/Header/index.styles.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/legacy/containers/Header/index.styles.ts b/src/app/legacy/containers/Header/index.styles.ts index 53e6228d513..ec02ca2a63f 100644 --- a/src/app/legacy/containers/Header/index.styles.ts +++ b/src/app/legacy/containers/Header/index.styles.ts @@ -80,7 +80,7 @@ export default { '& > div > div:last-child': { [mq.GROUP_0_MAX_WIDTH]: { flexBasis: '100%', - margin: `${spacings.FULL}rem 0`, + margin: `0 0 ${spacings.FULL}rem 0`, }, [mq.GROUP_1_MIN_WIDTH]: { display: 'flex', From c6fd8580de4ea8bb1c221bb7ce29f3382c3e176c Mon Sep 17 00:00:00 2001 From: Pedram Valiani Date: Wed, 8 Apr 2026 10:47:25 +0100 Subject: [PATCH 12/26] remove article specific check on ukchina not needed --- src/app/legacy/containers/Header/index.jsx | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/app/legacy/containers/Header/index.jsx b/src/app/legacy/containers/Header/index.jsx index 82485506e90..9b4d4108ea7 100644 --- a/src/app/legacy/containers/Header/index.jsx +++ b/src/app/legacy/containers/Header/index.jsx @@ -86,15 +86,12 @@ const HeaderContainer = ({ navItems, propsForTopBarOJComponent }) => { ); - const shouldUseNewNav = - SERVICES_WITH_NEW_NAV.includes(service) && - !(service === 'ukchina' && pageType !== ARTICLE_PAGE); + const shouldUseNewNav = SERVICES_WITH_NEW_NAV.includes(service); let shouldRenderScriptSwitch = false; if (scriptLink) { switch (true) { - case service === 'ukchina' && pageType !== ARTICLE_PAGE: case pageType === LIVE_PAGE: case service === 'uzbek' && ![ARTICLE_PAGE, HOME_PAGE, TOPIC_PAGE, ERROR_PAGE].includes(pageType): From 25b666e9b6ce8d03c417fb91781cda831631ecbd Mon Sep 17 00:00:00 2001 From: Pedram Valiani Date: Wed, 8 Apr 2026 10:48:04 +0100 Subject: [PATCH 13/26] update tests --- src/app/legacy/containers/Header/index.test.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/legacy/containers/Header/index.test.jsx b/src/app/legacy/containers/Header/index.test.jsx index f793e2fa8e8..c29b85b2120 100644 --- a/src/app/legacy/containers/Header/index.test.jsx +++ b/src/app/legacy/containers/Header/index.test.jsx @@ -169,7 +169,7 @@ describe(`Header`, () => { expect(container.querySelectorAll(scriptLinkSelector).length).toBe(1); }); - it('should not render script link for ukchina home pages', () => { + it('should render script link for ukchina home pages', () => { const { container } = HeaderContainerWithContext({ renderOptions: { pageType: HOME_PAGE, @@ -178,7 +178,7 @@ describe(`Header`, () => { }, }); - expect(container.querySelectorAll(scriptLinkSelector).length).toBe(0); + expect(container.querySelectorAll(scriptLinkSelector).length).toBe(1); }); describe('when service is uzbek', () => { From 206e4cc4584fd0341124394d126e0be4252a5d24 Mon Sep 17 00:00:00 2001 From: Pedram Valiani Date: Wed, 8 Apr 2026 10:59:06 +0100 Subject: [PATCH 14/26] remove isNewNavigation prop to use service list directly --- src/app/components/Header/ScriptLink/index.tsx | 9 ++------- src/app/legacy/containers/Header/index.jsx | 12 ++---------- 2 files changed, 4 insertions(+), 17 deletions(-) diff --git a/src/app/components/Header/ScriptLink/index.tsx b/src/app/components/Header/ScriptLink/index.tsx index 454cd4019fc..3573ffbae24 100644 --- a/src/app/components/Header/ScriptLink/index.tsx +++ b/src/app/components/Header/ScriptLink/index.tsx @@ -5,11 +5,7 @@ import SERVICES_WITH_NEW_NAV from '#app/components/Navigation/config'; import { ServiceContext } from '../../../contexts/ServiceContext'; import styles from './index.styles'; -type Props = { - isNewNavigation?: boolean; -}; - -const ScriptLink = ({ isNewNavigation = false }: Props) => { +const ScriptLink = () => { const { scriptLink, service } = use(ServiceContext); const { pathname, variant: currentVariant } = use(RequestContext); const { enabled: scriptLinkEnabled } = useToggle('scriptLink'); @@ -31,8 +27,7 @@ const ScriptLink = ({ isNewNavigation = false }: Props) => { pathPartsWithoutExtension[currentVariantIndex] = alternateVariant; const pathToVariant = pathPartsWithoutExtension.join('/'); - const useNewNavigationStyles = - isNewNavigation && SERVICES_WITH_NEW_NAV.includes(service); + const useNewNavigationStyles = SERVICES_WITH_NEW_NAV.includes(service); return ( {
- ) - } + scriptLink={shouldRenderScriptSwitch && } css={headerBrandCss} > @@ -133,11 +129,7 @@ const HeaderContainer = ({ navItems, propsForTopBarOJComponent }) => {
- ) - } + scriptLink={shouldRenderScriptSwitch && } css={headerBrandCss} > From 66825e25bacf168fb95ecfb41ed6f5bd469ac9d7 Mon Sep 17 00:00:00 2001 From: Pedram Valiani Date: Wed, 8 Apr 2026 10:59:25 +0100 Subject: [PATCH 15/26] update tests with isNewNavigation removed --- src/app/components/Header/ScriptLink/index.test.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/components/Header/ScriptLink/index.test.tsx b/src/app/components/Header/ScriptLink/index.test.tsx index 6f44059b1a8..877d58bc88a 100644 --- a/src/app/components/Header/ScriptLink/index.test.tsx +++ b/src/app/components/Header/ScriptLink/index.test.tsx @@ -26,7 +26,7 @@ describe(`Script Link`, () => { }); it('should render correctly for new navigation', () => { - const { container } = render(, { + const { container } = render(, { toggles: enabledToggleState, service: 'ukchina', variant: 'trad', From fc0f0dfb342bcbeb32b3d9ac2f6f6a32f89f5351 Mon Sep 17 00:00:00 2001 From: Pedram Valiani Date: Wed, 8 Apr 2026 10:59:36 +0100 Subject: [PATCH 16/26] update snapshots --- .../__snapshots__/index.test.tsx.snap | 84 ++++++++++--------- 1 file changed, 43 insertions(+), 41 deletions(-) diff --git a/src/app/components/Header/ScriptLink/__snapshots__/index.test.tsx.snap b/src/app/components/Header/ScriptLink/__snapshots__/index.test.tsx.snap index dacbf8e6593..a8133c26c98 100644 --- a/src/app/components/Header/ScriptLink/__snapshots__/index.test.tsx.snap +++ b/src/app/components/Header/ScriptLink/__snapshots__/index.test.tsx.snap @@ -2,60 +2,62 @@ exports[`Script Link should render correctly 1`] = ` .emotion-0 { - font-size: 0.9375rem; - line-height: 1.25rem; font-family: Helmet,Freesans,Helvetica,Arial,sans-serif; font-style: normal; font-weight: 400; - display: inline-block; + font-size: 0.9375rem; + line-height: 1; + position: relative; + display: -webkit-inline-box; + display: -webkit-inline-flex; + display: -ms-inline-flexbox; + display: inline-flex; + -webkit-align-items: stretch; + -webkit-box-align: stretch; + -ms-flex-align: stretch; + align-items: stretch; + -webkit-box-pack: center; + -ms-flex-pack: center; + -webkit-justify-content: center; + justify-content: center; + box-sizing: border-box; color: #FFFFFF; -webkit-text-decoration: none; text-decoration: none; - height: 2.75rem; + height: 2.25rem; + min-width: 2.125rem; border: 0.0625rem solid #FFFFFF; - margin: 0.5rem 0 0.5rem 0.5rem; - min-width: 2.75rem; text-align: center; + white-space: nowrap; } -@media (min-width: 20rem) and (max-width: 37.4375rem) { - .emotion-0 { - font-size: 1rem; - line-height: 1.25rem; - } -} - -@media (min-width: 37.5rem) { - .emotion-0 { - font-size: 1rem; - line-height: 1.25rem; - } -} - -.emotion-0:focus span, -.emotion-0:hover span { - margin: 0; - border: 0.1875rem solid #FFFFFF; -} - -@media (min-width: 25rem) { - .emotion-0 { - line-height: calc(2.25rem - 0.5rem); - } -} - -@media (max-width: 24.9375rem) { - .emotion-0 { - margin: 0.5rem 0 0.5rem 0; - } +.emotion-0:focus::after, +.emotion-0:hover::after { + content: ""; + position: absolute; + inset: 0; + box-sizing: border-box; + border: 0.25rem solid #FFFFFF; + pointer-events: none; } .emotion-1 { - margin-top: 0.1875rem; - width: 100%; - display: inline-block; - height: calc(100%); - line-height: calc(2.75rem - 0.5rem); + display: -webkit-inline-box; + display: -webkit-inline-flex; + display: -ms-inline-flexbox; + display: inline-flex; + -webkit-align-items: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -ms-flex-pack: center; + -webkit-justify-content: center; + justify-content: center; + box-sizing: border-box; + height: 100%; + padding-inline: 0.375rem; + line-height: 1; }
From b5434ee3f35ec63b3f743b31a718bd92c273d73b Mon Sep 17 00:00:00 2001 From: Pedram Valiani Date: Wed, 8 Apr 2026 11:11:11 +0100 Subject: [PATCH 17/26] updates to styling to separate out classes for easier deletion --- .../Header/ScriptLink/index.styles.ts | 144 +++++++++--------- .../components/Header/ScriptLink/index.tsx | 18 +-- 2 files changed, 75 insertions(+), 87 deletions(-) diff --git a/src/app/components/Header/ScriptLink/index.styles.ts b/src/app/components/Header/ScriptLink/index.styles.ts index f954e8bb60b..4b0f9f2d615 100644 --- a/src/app/components/Header/ScriptLink/index.styles.ts +++ b/src/app/components/Header/ScriptLink/index.styles.ts @@ -2,80 +2,74 @@ import pixelsToRem from '#app/utilities/pixelsToRem'; import { css, Theme } from '@emotion/react'; const styles = { - link: ( - { fontSizes, fontVariants, palette, spacings, mq }: Theme, - { isNewNavigation = false }: { isNewNavigation?: boolean } = {}, - ) => - isNewNavigation - ? css({ - ...fontVariants.sansRegular, - fontSize: `${pixelsToRem(15)}rem`, - lineHeight: 1, - position: 'relative', - display: 'inline-flex', - alignItems: 'stretch', - justifyContent: 'center', - boxSizing: 'border-box', - color: palette.WHITE, - textDecoration: 'none', - height: `${pixelsToRem(36)}rem`, - minWidth: `${pixelsToRem(34)}rem`, - border: `${pixelsToRem(1)}rem solid ${palette.WHITE}`, - textAlign: 'center', - whiteSpace: 'nowrap', - '&:focus::after, &:hover::after': { - content: '""', - position: 'absolute', - inset: 0, - boxSizing: 'border-box', - border: `${pixelsToRem(4)}rem solid ${palette.WHITE}`, - pointerEvents: 'none', - }, - }) - : css({ - ...fontSizes.pica, - ...fontVariants.sansRegular, - display: 'inline-block', - color: palette.WHITE, - textDecoration: 'none', - height: '2.75rem', - border: `0.0625rem solid ${palette.WHITE}`, - margin: `${spacings.FULL}rem 0 ${spacings.FULL}rem ${spacings.FULL}rem`, - minWidth: '2.75rem', - textAlign: 'center', - '&:focus, &:hover': { - span: { - margin: '0', - border: `0.1875rem solid ${palette.WHITE}`, - }, - }, - [mq.GROUP_2_MIN_WIDTH]: { - lineHeight: `calc(2.25rem - ${spacings.FULL}rem)`, - }, - [mq.GROUP_1_MAX_WIDTH]: { - margin: `${spacings.FULL}rem 0 ${spacings.FULL}rem 0`, - }, - }), - container: ( - { spacings }: Theme, - { isNewNavigation = false }: { isNewNavigation?: boolean } = {}, - ) => - isNewNavigation - ? css({ - display: 'inline-flex', - alignItems: 'center', - justifyContent: 'center', - boxSizing: 'border-box', - height: '100%', - paddingInline: `${pixelsToRem(6)}rem`, - lineHeight: 1, - }) - : css({ - marginTop: '0.1875rem', - width: '100%', - display: 'inline-block', - height: 'calc(100%)', - lineHeight: `calc(2.75rem - ${spacings.FULL}rem)`, - }), + link: ({ fontSizes, fontVariants, palette, spacings, mq }: Theme) => + css({ + ...fontSizes.pica, + ...fontVariants.sansRegular, + display: 'inline-block', + color: palette.WHITE, + textDecoration: 'none', + height: '2.75rem', + border: `0.0625rem solid ${palette.WHITE}`, + margin: `${spacings.FULL}rem 0 ${spacings.FULL}rem ${spacings.FULL}rem`, + minWidth: '2.75rem', + textAlign: 'center', + '&:focus, &:hover': { + span: { + margin: '0', + border: `0.1875rem solid ${palette.WHITE}`, + }, + }, + [mq.GROUP_2_MIN_WIDTH]: { + lineHeight: `calc(2.25rem - ${spacings.FULL}rem)`, + }, + [mq.GROUP_1_MAX_WIDTH]: { + margin: `${spacings.FULL}rem 0 ${spacings.FULL}rem 0`, + }, + }), + newNavLink: ({ fontVariants, palette }: Theme) => + css({ + ...fontVariants.sansRegular, + fontSize: `${pixelsToRem(15)}rem`, + lineHeight: 1, + position: 'relative', + display: 'inline-flex', + alignItems: 'stretch', + justifyContent: 'center', + boxSizing: 'border-box', + color: palette.WHITE, + textDecoration: 'none', + height: `${pixelsToRem(36)}rem`, + minWidth: `${pixelsToRem(34)}rem`, + border: `${pixelsToRem(1)}rem solid ${palette.WHITE}`, + textAlign: 'center', + whiteSpace: 'nowrap', + '&:focus::after, &:hover::after': { + content: '""', + position: 'absolute', + inset: 0, + boxSizing: 'border-box', + border: `${pixelsToRem(4)}rem solid ${palette.WHITE}`, + pointerEvents: 'none', + }, + }), + container: ({ spacings }: Theme) => + css({ + marginTop: '0.1875rem', + width: '100%', + display: 'inline-block', + height: 'calc(100%)', + lineHeight: `calc(2.75rem - ${spacings.FULL}rem)`, + }), + newNavContainer: () => + css({ + display: 'inline-flex', + alignItems: 'center', + justifyContent: 'center', + boxSizing: 'border-box', + height: '100%', + paddingInline: `${pixelsToRem(6)}rem`, + lineHeight: 1, + }), }; export default styles; diff --git a/src/app/components/Header/ScriptLink/index.tsx b/src/app/components/Header/ScriptLink/index.tsx index 3573ffbae24..4cc7b02381a 100644 --- a/src/app/components/Header/ScriptLink/index.tsx +++ b/src/app/components/Header/ScriptLink/index.tsx @@ -28,25 +28,19 @@ const ScriptLink = () => { pathPartsWithoutExtension[currentVariantIndex] = alternateVariant; const pathToVariant = pathPartsWithoutExtension.join('/'); const useNewNavigationStyles = SERVICES_WITH_NEW_NAV.includes(service); + const linkStyles = useNewNavigationStyles ? styles.newNavLink : styles.link; + const containerStyles = useNewNavigationStyles + ? styles.newNavContainer + : styles.container; return ( - styles.link(theme, { isNewNavigation: useNewNavigationStyles }) - } + css={linkStyles} href={pathToVariant} data-variant={alternateVariant} className="focusIndicatorRemove" > - - styles.container(theme, { - isNewNavigation: useNewNavigationStyles, - }) - } - > - {text} - + {text} ); }; From 989800bbd5eb3ae665f7297432f209465b73cecf Mon Sep 17 00:00:00 2001 From: Pedram Valiani Date: Wed, 8 Apr 2026 13:37:36 +0100 Subject: [PATCH 18/26] add class selector to psammead brand for new nav script link style --- src/app/legacy/psammead/psammead-brand/src/index.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/legacy/psammead/psammead-brand/src/index.jsx b/src/app/legacy/psammead/psammead-brand/src/index.jsx index 66ee52cc54b..c4b5f13aeff 100644 --- a/src/app/legacy/psammead/psammead-brand/src/index.jsx +++ b/src/app/legacy/psammead/psammead-brand/src/index.jsx @@ -157,7 +157,7 @@ const Brand = forwardRef((props, ref) => { return ( - + {url ? ( { )} {skipLink} {children} - {scriptLink &&
{scriptLink}
} + {scriptLink &&
{scriptLink}
}
); From 3dea0d1bff94f26933d94a69954afda28435325b Mon Sep 17 00:00:00 2001 From: Pedram Valiani Date: Wed, 8 Apr 2026 13:38:12 +0100 Subject: [PATCH 19/26] adjust headerBrand to use min height for script link --- .../legacy/containers/Header/index.styles.ts | 20 +++++++------------ 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/src/app/legacy/containers/Header/index.styles.ts b/src/app/legacy/containers/Header/index.styles.ts index ec02ca2a63f..5e49fa0ae16 100644 --- a/src/app/legacy/containers/Header/index.styles.ts +++ b/src/app/legacy/containers/Header/index.styles.ts @@ -32,25 +32,22 @@ export default { { hasScriptLink = false }: { hasScriptLink?: boolean } = {}, ) => css({ - minHeight: 'auto', - height: `${pixelsToRem(MAX_NAV_ITEM_HEIGHT)}rem`, + minHeight: `${pixelsToRem(MAX_NAV_ITEM_HEIGHT)}rem`, [mq.GROUP_1_MIN_WIDTH]: { minHeight: 'auto', }, [mq.GROUP_2_MIN_WIDTH]: { - minHeight: 'auto', padding: `0 ${spacings.FULL}rem`, - height: `${pixelsToRem(MAX_NAV_ITEM_HEIGHT)}rem`, + minHeight: `${pixelsToRem(MAX_NAV_ITEM_HEIGHT)}rem`, }, [mq.GROUP_3_MIN_WIDTH]: { - minHeight: 'auto', padding: `0 ${spacings.DOUBLE}rem`, - height: `${pixelsToRem(MAX_NAV_ITEM_HEIGHT)}rem`, + minHeight: `${pixelsToRem(MAX_NAV_ITEM_HEIGHT)}rem`, }, - '& > div > a:first-of-type': { + '#topPage, #brandLink': { paddingTop: `${pixelsToRem(2)}rem`, svg: { @@ -63,21 +60,18 @@ export default { }, ...(hasScriptLink && { - [mq.GROUP_0_MAX_WIDTH]: { - height: 'auto', - }, - '& > div': { + '.brand-svg-wrapper': { [mq.GROUP_1_MIN_WIDTH]: { flexWrap: 'nowrap', }, }, - '& > div > a:first-of-type': { + '#topPage, #brandLink': { [mq.GROUP_1_MIN_WIDTH]: { flex: '0 1 auto', minWidth: 0, }, }, - '& > div > div:last-child': { + '.script-link-wrapper': { [mq.GROUP_0_MAX_WIDTH]: { flexBasis: '100%', margin: `0 0 ${spacings.FULL}rem 0`, From 3d732683838d7f6132950ff159477a7c3b949b51 Mon Sep 17 00:00:00 2001 From: Pedram Valiani Date: Wed, 8 Apr 2026 13:38:25 +0100 Subject: [PATCH 20/26] update snapshots --- .../containers/Brand/__snapshots__/index.test.jsx.snap | 2 +- .../containers/Header/__snapshots__/index.test.jsx.snap | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/app/legacy/containers/Brand/__snapshots__/index.test.jsx.snap b/src/app/legacy/containers/Brand/__snapshots__/index.test.jsx.snap index 993119b8c04..de19fe97272 100644 --- a/src/app/legacy/containers/Brand/__snapshots__/index.test.jsx.snap +++ b/src/app/legacy/containers/Brand/__snapshots__/index.test.jsx.snap @@ -147,7 +147,7 @@ exports[`BrandContainer should render correctly 1`] = ` class="emotion-0 emotion-1 emotion-2" >
Date: Wed, 8 Apr 2026 13:52:32 +0100 Subject: [PATCH 21/26] update snapshots --- .../PageLayoutWrapper/__snapshots__/index.test.tsx.snap | 4 ++-- .../containers/Footer/__snapshots__/index.test.jsx.snap | 2 +- .../psammead-brand/src/__snapshots__/index.test.jsx.snap | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/app/components/PageLayoutWrapper/__snapshots__/index.test.tsx.snap b/src/app/components/PageLayoutWrapper/__snapshots__/index.test.tsx.snap index 439fa34d4ca..bdec3d1a326 100644 --- a/src/app/components/PageLayoutWrapper/__snapshots__/index.test.tsx.snap +++ b/src/app/components/PageLayoutWrapper/__snapshots__/index.test.tsx.snap @@ -1198,7 +1198,7 @@ exports[`PageLayoutWrapper should render default page wrapper with children 1`] class="emotion-17 emotion-18 emotion-19" >