@financial-times/dotcom-ui-header 9.0.0-beta.14 → 9.0.0-beta.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/browser.js CHANGED
@@ -1,12 +1,10 @@
1
1
  import Header from '@financial-times/o-header'
2
2
  import TopicSearch from 'n-topic-search'
3
- import EnhancedSearch from './src/enhanced-search/enhancedSearch'
3
+
4
4
  /**
5
5
  * @typedef HeaderOptions
6
6
  * @property { HTMLElement } [rootElement] - the root element passed to o-header
7
7
  * @property { string } [hostName]
8
- * @property { 'open' | 'close' } [searchState]
9
- * @property { string } [enhancedSearchUrl]
10
8
  */
11
9
 
12
10
  /**
@@ -18,17 +16,10 @@ export const init = (headerOptions = {}) => {
18
16
  '.o-header [data-n-topic-search], .o-header__drawer [data-n-topic-search]'
19
17
  )
20
18
  topicSearchElements.forEach((element) => {
21
- headerOptions.enhancedSearchUrl
22
- ? new EnhancedSearch(element, headerOptions)
23
- : new TopicSearch(element, headerOptions)
19
+ new TopicSearch(element, headerOptions)
24
20
  })
25
21
 
26
- Header.init(headerOptions.rootElement, { searchState: headerOptions.searchState })
27
-
28
- if (headerOptions.searchState === 'open') {
29
- // Hide the sticky heder
30
- document.querySelector('#o-header-search-sticky')?.setAttribute('aria-hidden', 'true')
31
- }
22
+ Header.init(headerOptions.rootElement)
32
23
  }
33
24
 
34
25
  export { Header as OrigamiHeader }
@@ -31,12 +31,8 @@ const NavListRightAnonSticky = (props) => {
31
31
  subscribeAction && (react_1.default.createElement(partials_1.SubscribeButton, { item: subscribeAction, variant: "sticky", className: "o-header__top-button--hide-m" })),
32
32
  signInAction && react_1.default.createElement(partials_1.SignInLink, { item: signInAction, variant: "sticky", className: "" }))));
33
33
  };
34
- const MyFtSticky = ({ className, items }) => {
35
- var _a;
36
- const ftUrl = (_a = items === null || items === void 0 ? void 0 : items.find((el) => el.label === 'myFT')) === null || _a === void 0 ? void 0 : _a.url;
37
- return (react_1.default.createElement("a", { className: `o-header__top-icon-link o-header__top-icon-link--myft ${className}`, href: ftUrl !== null && ftUrl !== void 0 ? ftUrl : '/myft', "data-trackable": "my-ft", tabIndex: -1 },
38
- react_1.default.createElement("span", { className: "o-header__visually-hidden" }, "myFT")));
39
- };
34
+ const MyFtSticky = ({ className }) => (react_1.default.createElement("a", { className: `o-header__top-icon-link o-header__top-icon-link--myft ${className}`, href: "/myft", "data-trackable": "my-ft", tabIndex: -1 },
35
+ react_1.default.createElement("span", { className: "o-header__visually-hidden" }, "myFT")));
40
36
  const TopWrapperSticky = (props) => (react_1.default.createElement("div", { className: "o-header__row o-header__top", "data-trackable": "header-sticky" },
41
37
  react_1.default.createElement("div", { className: "o-header__container" },
42
38
  react_1.default.createElement("div", { className: "o-header__top-wrapper" }, props.children))));
@@ -54,11 +50,11 @@ const TopColumnCenterSticky = (props) => {
54
50
  };
55
51
  exports.TopColumnCenterSticky = TopColumnCenterSticky;
56
52
  const NavListRightLoggedInSticky = (props) => {
57
- var _a, _b;
53
+ var _a;
58
54
  const subscribeAction = (_a = props.data['navbar-right-anon'].items) === null || _a === void 0 ? void 0 : _a[1];
59
55
  return (react_1.default.createElement(react_1.default.Fragment, null,
60
56
  !props.userIsSubscribed && subscribeAction && (react_1.default.createElement(partials_1.SubscribeButton, { item: subscribeAction, variant: "sticky", className: "o-header__top-button--hide-m" })),
61
- react_1.default.createElement(MyFtSticky, { className: "", items: (_b = props.data.account) === null || _b === void 0 ? void 0 : _b.items })));
57
+ react_1.default.createElement(MyFtSticky, { className: "" })));
62
58
  };
63
59
  // This behaviour is similar to `NavListRight` in '../navigation/partials' but:
64
60
  // - The sticky header renders either the `navbar-right-anon` data or the myFT component
@@ -4,9 +4,7 @@ import { TNavMenuItem } from '@financial-times/dotcom-types-navigation';
4
4
  declare const HeaderWrapper: (props: any) => JSX.Element;
5
5
  declare const TopWrapper: (props: any) => JSX.Element;
6
6
  declare const TopColumnLeft: () => JSX.Element;
7
- declare const TopColumnCenter: ({ url }: {
8
- url?: string | undefined;
9
- }) => JSX.Element;
7
+ declare const TopColumnCenter: () => JSX.Element;
10
8
  declare const TopColumnCenterNoLink: () => JSX.Element;
11
9
  declare const SignInLink: ({ item, variant, className }: {
12
10
  item: TNavMenuItem;
@@ -12,12 +12,8 @@ const DrawerIcon = () => (react_1.default.createElement("a", { href: "#o-header-
12
12
  react_1.default.createElement("span", { className: "o-header__top-link-label" }, "Open side navigation menu")));
13
13
  const SearchIcon = () => (react_1.default.createElement("a", { href: `#o-header-search-primary`, className: "o-header__top-icon-link o-header__top-icon-link--search", "aria-controls": `o-header-search-primary`, title: "Open search bar", "data-trackable": "search-toggle" },
14
14
  react_1.default.createElement("span", { className: "o-header__top-link-label" }, "Open search bar")));
15
- const MyFt = ({ className, items }) => {
16
- var _a;
17
- const ftUrl = (_a = items === null || items === void 0 ? void 0 : items.find((el) => el.label === 'myFT')) === null || _a === void 0 ? void 0 : _a.url;
18
- return (react_1.default.createElement("a", { className: `o-header__top-icon-link o-header__top-icon-link--myft ${className}`, id: "o-header-top-link-myft", href: ftUrl !== null && ftUrl !== void 0 ? ftUrl : '/myft', "data-trackable": "my-ft", "data-tour-stage": "myFt", "aria-label": "My F T" },
19
- react_1.default.createElement("span", { className: "o-header__visually-hidden" }, "myFT")));
20
- };
15
+ const MyFt = ({ className }) => (react_1.default.createElement("a", { className: `o-header__top-icon-link o-header__top-icon-link--myft ${className}`, id: "o-header-top-link-myft", href: "/myft", "data-trackable": "my-ft", "data-tour-stage": "myFt", "aria-label": "My F T" },
16
+ react_1.default.createElement("span", { className: "o-header__visually-hidden" }, "myFT")));
21
17
  const TopWrapper = (props) => (react_1.default.createElement("div", { className: "o-header__row o-header__top", "data-trackable": "header-top" },
22
18
  react_1.default.createElement("div", { className: "o-header__container" },
23
19
  react_1.default.createElement("div", { className: "o-header__top-wrapper" }, props.children))));
@@ -26,8 +22,8 @@ const TopColumnLeft = () => (react_1.default.createElement("div", { className: "
26
22
  react_1.default.createElement(DrawerIcon, null),
27
23
  react_1.default.createElement(SearchIcon, null)));
28
24
  exports.TopColumnLeft = TopColumnLeft;
29
- const TopColumnCenter = ({ url }) => (react_1.default.createElement("div", { className: "o-header__top-column o-header__top-column--center" },
30
- react_1.default.createElement("a", { className: "o-header__top-logo", style: { backgroundImage: 'none' }, "data-trackable": "logo", href: url !== null && url !== void 0 ? url : '/', title: "Go to Financial Times homepage" },
25
+ const TopColumnCenter = () => (react_1.default.createElement("div", { className: "o-header__top-column o-header__top-column--center" },
26
+ react_1.default.createElement("a", { className: "o-header__top-logo", style: { backgroundImage: 'none' }, "data-trackable": "logo", href: "/", title: "Go to Financial Times homepage" },
31
27
  react_1.default.createElement(BrandFtMasthead_1.default, { title: "Financial Times" }))));
32
28
  exports.TopColumnCenter = TopColumnCenter;
33
29
  const TopColumnCenterNoLink = () => (react_1.default.createElement("div", { className: "o-header__top-column o-header__top-column--center" },
@@ -35,11 +31,11 @@ const TopColumnCenterNoLink = () => (react_1.default.createElement("div", { clas
35
31
  react_1.default.createElement(BrandFtMasthead_1.default, { title: "Financial Times" }))));
36
32
  exports.TopColumnCenterNoLink = TopColumnCenterNoLink;
37
33
  const TopColumnRightLoggedIn = (props) => {
38
- var _a, _b, _c, _d;
34
+ var _a, _b;
39
35
  const subscribeAction = (_b = (_a = props.data['navbar-right-anon']) === null || _a === void 0 ? void 0 : _a.items) === null || _b === void 0 ? void 0 : _b[1];
40
36
  return (react_1.default.createElement("div", { className: "o-header__top-column o-header__top-column--right" },
41
37
  !props.userIsSubscribed && subscribeAction && (react_1.default.createElement(SubscribeButton, { item: subscribeAction, variant: props.variant, className: "o-header__top-button--hide-m" })),
42
- react_1.default.createElement(MyFt, { className: "", items: (_d = (_c = props.data) === null || _c === void 0 ? void 0 : _c.account) === null || _d === void 0 ? void 0 : _d.items })));
38
+ react_1.default.createElement(MyFt, { className: "" })));
43
39
  };
44
40
  const SignInLink = ({ item, variant, className }) => {
45
41
  var _a;
@@ -62,18 +58,16 @@ const TopColumnRightAnon = ({ items, variant }) => {
62
58
  return (react_1.default.createElement("div", { className: "o-header__top-column o-header__top-column--right" },
63
59
  subscribeAction && (react_1.default.createElement(SubscribeButton, { item: subscribeAction, variant: variant, className: "o-header__top-button--hide-m" })),
64
60
  signInAction && (react_1.default.createElement(SignInLink, { item: signInAction, variant: variant, className: "o-header__top-link--hide-m" })),
65
- react_1.default.createElement(MyFt, { className: "o-header__top-icon-link--show-m", items: items })));
61
+ react_1.default.createElement(MyFt, { className: "o-header__top-icon-link--show-m" })));
66
62
  };
67
63
  exports.TopColumnRightAnon = TopColumnRightAnon;
68
64
  const TopColumnRight = (props) => {
69
- var _a, _b;
70
65
  if (props.userIsLoggedIn) {
71
66
  return react_1.default.createElement(TopColumnRightLoggedIn, Object.assign({}, props));
72
67
  }
73
68
  else {
74
69
  const userNavAnonItems = props.data['navbar-right-anon'].items;
75
- const userNavAccountItems = (_b = (_a = props.data.account) === null || _a === void 0 ? void 0 : _a.items) !== null && _b !== void 0 ? _b : [];
76
- return react_1.default.createElement(TopColumnRightAnon, { items: userNavAnonItems.concat(userNavAccountItems), variant: props.variant });
70
+ return react_1.default.createElement(TopColumnRightAnon, { items: userNavAnonItems, variant: props.variant });
77
71
  }
78
72
  };
79
73
  exports.TopColumnRight = TopColumnRight;
@@ -20,14 +20,13 @@ const defaultProps = {
20
20
  showMegaNav: true
21
21
  };
22
22
  function MainHeader(props) {
23
- var _a, _b;
24
23
  const includeUserActionsNav = props.showUserNavigation && !props.userIsLoggedIn;
25
24
  const includeSubNavigation = props.showSubNavigation && (props.data.breadcrumb || props.data.subsections);
26
25
  return (react_1.default.createElement(partials_1.HeaderWrapper, Object.assign({}, props),
27
26
  includeUserActionsNav ? react_1.default.createElement(partials_2.UserActionsNav, Object.assign({}, props)) : null,
28
27
  react_1.default.createElement(partials_1.TopWrapper, null,
29
28
  react_1.default.createElement(partials_1.TopColumnLeft, null),
30
- props.showLogoLink ? (react_1.default.createElement(partials_1.TopColumnCenter, { url: (_b = (_a = props.data.editions) === null || _a === void 0 ? void 0 : _a.current) === null || _b === void 0 ? void 0 : _b.url })) : (react_1.default.createElement(partials_1.TopColumnCenterNoLink, null)),
29
+ props.showLogoLink ? react_1.default.createElement(partials_1.TopColumnCenter, null) : react_1.default.createElement(partials_1.TopColumnCenterNoLink, null),
31
30
  react_1.default.createElement(partials_1.TopColumnRight, Object.assign({}, props))),
32
31
  react_1.default.createElement(partials_5.Search, { instance: "primary" }),
33
32
  react_1.default.createElement(partials_2.MobileNav, Object.assign({}, props)),
@@ -67,12 +66,11 @@ function Drawer(props) {
67
66
  exports.Drawer = Drawer;
68
67
  Drawer.defaultProps = defaultProps;
69
68
  function NoOutboundLinksHeader(props) {
70
- var _a, _b;
71
69
  const includeUserActionsNav = props.showUserNavigation && !props.userIsLoggedIn;
72
70
  const includeSubNavigation = props.showSubNavigation && (props.data.breadcrumb || props.data.subsections);
73
71
  return (react_1.default.createElement(partials_1.HeaderWrapper, Object.assign({}, props),
74
72
  includeUserActionsNav ? react_1.default.createElement(partials_2.UserActionsNav, Object.assign({}, props)) : null,
75
- react_1.default.createElement(partials_1.TopWrapper, null, props.showLogoLink ? (react_1.default.createElement(partials_1.TopColumnCenter, { url: (_b = (_a = props.data.editions) === null || _a === void 0 ? void 0 : _a.current) === null || _b === void 0 ? void 0 : _b.url })) : (react_1.default.createElement(partials_1.TopColumnCenterNoLink, null))),
73
+ react_1.default.createElement(partials_1.TopWrapper, null, props.showLogoLink ? react_1.default.createElement(partials_1.TopColumnCenter, null) : react_1.default.createElement(partials_1.TopColumnCenterNoLink, null)),
76
74
  react_1.default.createElement(partials_2.NavDesktop, null, props.showUserNavigation ? react_1.default.createElement(partials_2.NavListRight, Object.assign({}, props)) : null),
77
75
  includeSubNavigation ? react_1.default.createElement(partials_4.SubNavigation, Object.assign({}, props)) : null));
78
76
  }
@@ -182,8 +182,8 @@
182
182
  "affectsGlobalScope": false
183
183
  },
184
184
  "../src/components/top/partials.tsx": {
185
- "version": "87cbe39a584f2dc0fcf77dbccd2d72880ae938a0692243b2b3b4c2639eed747e",
186
- "signature": "77e2a1005d3885487e05d8fbb99862703ec1e3230b16b31970b731a124f19414",
185
+ "version": "6fe24079686c1fafe3d97037422d0bf6145f3248984965d30629f2311450bbae",
186
+ "signature": "6d57836ef5d062f35a4e267bb19798b0711e7aa5a991fac64390a00f72c950be",
187
187
  "affectsGlobalScope": false
188
188
  },
189
189
  "../src/utils.ts": {
@@ -197,7 +197,7 @@
197
197
  "affectsGlobalScope": false
198
198
  },
199
199
  "../src/components/sticky/partials.tsx": {
200
- "version": "f8dd9197528a0ccdacf58885773f78a59e1243c3189eb73e810fdfbfc66b28fb",
200
+ "version": "48ac973f374d580296150e16e99c89dfc3717b11dd52080ec6cc309a740829c7",
201
201
  "signature": "502016ae45d32bca27cbd9d67cf6f390647cb4b8db18384814c9539213d40fba",
202
202
  "affectsGlobalScope": false
203
203
  },
@@ -222,7 +222,7 @@
222
222
  "affectsGlobalScope": false
223
223
  },
224
224
  "../src/index.tsx": {
225
- "version": "5e57493c4c31180ed6b73ef9da15c8b041a49351db43162cc5f96f0e3b78980e",
225
+ "version": "f076cad62acf3ca2bca2348a445aeef886e7c0db4ae610eafba754942df1fbec",
226
226
  "signature": "193a1c1b82fe624c251dd16b488b6b90a155e072da0ace6b843ec85f99df0c6e",
227
227
  "affectsGlobalScope": false
228
228
  },
@@ -1385,7 +1385,6 @@
1385
1385
  ],
1386
1386
  "../src/components/sticky/partials.tsx": [
1387
1387
  "../../../node_modules/@types/react/index.d.ts",
1388
- "../../dotcom-types-navigation/index.d.ts",
1389
1388
  "../src/components/top/partials.tsx",
1390
1389
  "../src/interfaces.d.ts"
1391
1390
  ],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@financial-times/dotcom-ui-header",
3
- "version": "9.0.0-beta.14",
3
+ "version": "9.0.0-beta.15",
4
4
  "description": "",
5
5
  "browser": "browser.js",
6
6
  "main": "component.js",
@@ -22,22 +22,21 @@
22
22
  "author": "",
23
23
  "license": "MIT",
24
24
  "dependencies": {
25
- "@financial-times/dotcom-types-navigation": "^9.0.0-beta.14",
26
- "n-topic-search": "^6.1.0",
25
+ "@financial-times/dotcom-types-navigation": "^9.0.0-beta.15",
26
+ "n-topic-search": "^4.0.0",
27
27
  "n-ui-foundations": "^9.0.0"
28
28
  },
29
29
  "devDependencies": {
30
30
  "@financial-times/logo-images": "^1.10.1",
31
- "@financial-times/o-header": "^11.1.0",
32
31
  "@svgr/core": "^5.0.0",
33
32
  "camelcase": "^6.0.0",
34
33
  "check-engine": "^1.10.1",
34
+ "@financial-times/o-header": "^11.0.4",
35
35
  "react": "^16.8.6"
36
36
  },
37
37
  "peerDependencies": {
38
+ "@financial-times/o-header": "^11.0.4",
38
39
  "@financial-times/logo-images": "^1.10.1",
39
- "@financial-times/o-header": "^11.1.0",
40
- "@financial-times/o-message": "^5.4.3",
41
40
  "react": "16.x || 17.x"
42
41
  },
43
42
  "engines": {
@@ -54,7 +54,7 @@ exports[`dotcom-ui-header/src/components/MainHeader renders a right aligned subn
54
54
  <a
55
55
  className="o-header__top-logo"
56
56
  data-trackable="logo"
57
- href="#"
57
+ href="/"
58
58
  style={
59
59
  Object {
60
60
  "backgroundImage": "none",
@@ -1897,7 +1897,7 @@ exports[`dotcom-ui-header/src/components/MainHeader renders as a logged in user
1897
1897
  <a
1898
1898
  className="o-header__top-logo"
1899
1899
  data-trackable="logo"
1900
- href="#"
1900
+ href="/"
1901
1901
  style={
1902
1902
  Object {
1903
1903
  "backgroundImage": "none",
@@ -3745,7 +3745,7 @@ exports[`dotcom-ui-header/src/components/MainHeader renders as an anonymous user
3745
3745
  <a
3746
3746
  className="o-header__top-logo"
3747
3747
  data-trackable="logo"
3748
- href="#"
3748
+ href="/"
3749
3749
  style={
3750
3750
  Object {
3751
3751
  "backgroundImage": "none",
@@ -4,7 +4,6 @@
4
4
  import React from 'react'
5
5
  import { SubscribeButton, SignInLink } from '../top/partials'
6
6
  import { THeaderProps } from '../../interfaces'
7
- import { TNavMenuItem } from '@financial-times/dotcom-types-navigation'
8
7
 
9
8
  const StickyHeaderWrapper = (props: THeaderProps & { children: React.ReactNode }) => (
10
9
  <header
@@ -89,19 +88,16 @@ const NavListRightAnonSticky = (props: THeaderProps) => {
89
88
  )
90
89
  }
91
90
 
92
- const MyFtSticky = ({ className, items }: { className?: string; items?: TNavMenuItem[] }) => {
93
- const ftUrl = items?.find((el) => el.label === 'myFT')?.url
94
- return (
95
- <a
96
- className={`o-header__top-icon-link o-header__top-icon-link--myft ${className}`}
97
- href={ftUrl ?? '/myft'}
98
- data-trackable="my-ft"
99
- tabIndex={-1}
100
- >
101
- <span className="o-header__visually-hidden">myFT</span>
102
- </a>
103
- )
104
- }
91
+ const MyFtSticky = ({ className }: { className?: string }) => (
92
+ <a
93
+ className={`o-header__top-icon-link o-header__top-icon-link--myft ${className}`}
94
+ href="/myft"
95
+ data-trackable="my-ft"
96
+ tabIndex={-1}
97
+ >
98
+ <span className="o-header__visually-hidden">myFT</span>
99
+ </a>
100
+ )
105
101
 
106
102
  const TopWrapperSticky = (props) => (
107
103
  <div className="o-header__row o-header__top" data-trackable="header-sticky">
@@ -133,9 +129,13 @@ const NavListRightLoggedInSticky = (props: THeaderProps) => {
133
129
  return (
134
130
  <React.Fragment>
135
131
  {!props.userIsSubscribed && subscribeAction && (
136
- <SubscribeButton item={subscribeAction} variant="sticky" className="o-header__top-button--hide-m" />
132
+ <SubscribeButton
133
+ item={subscribeAction}
134
+ variant="sticky"
135
+ className="o-header__top-button--hide-m"
136
+ />
137
137
  )}
138
- <MyFtSticky className="" items={props.data.account?.items} />
138
+ <MyFtSticky className="" />
139
139
  </React.Fragment>
140
140
  )
141
141
  }
@@ -39,21 +39,18 @@ const SearchIcon = () => (
39
39
  </a>
40
40
  )
41
41
 
42
- const MyFt = ({ className, items }: { className?: string; items?: TNavMenuItem[] }) => {
43
- const ftUrl = items?.find((el) => el.label === 'myFT')?.url
44
- return (
45
- <a
46
- className={`o-header__top-icon-link o-header__top-icon-link--myft ${className}`}
47
- id="o-header-top-link-myft"
48
- href={ftUrl ?? '/myft'}
49
- data-trackable="my-ft"
50
- data-tour-stage="myFt"
51
- aria-label="My F T"
52
- >
53
- <span className="o-header__visually-hidden">myFT</span>
54
- </a>
55
- )
56
- }
42
+ const MyFt = ({ className }: { className?: string }) => (
43
+ <a
44
+ className={`o-header__top-icon-link o-header__top-icon-link--myft ${className}`}
45
+ id="o-header-top-link-myft"
46
+ href="/myft"
47
+ data-trackable="my-ft"
48
+ data-tour-stage="myFt"
49
+ aria-label="My F T"
50
+ >
51
+ <span className="o-header__visually-hidden">myFT</span>
52
+ </a>
53
+ )
57
54
 
58
55
  const TopWrapper = (props) => (
59
56
  <div className="o-header__row o-header__top" data-trackable="header-top">
@@ -70,13 +67,13 @@ const TopColumnLeft = () => (
70
67
  </div>
71
68
  )
72
69
 
73
- const TopColumnCenter = ({ url }: { url?: string }) => (
70
+ const TopColumnCenter = () => (
74
71
  <div className="o-header__top-column o-header__top-column--center">
75
72
  <a
76
73
  className="o-header__top-logo"
77
74
  style={{ backgroundImage: 'none' }}
78
75
  data-trackable="logo"
79
- href={url ?? '/'}
76
+ href="/"
80
77
  title="Go to Financial Times homepage"
81
78
  >
82
79
  <BrandFtMastheadSvg title="Financial Times" />
@@ -103,7 +100,7 @@ const TopColumnRightLoggedIn = (props: THeaderProps) => {
103
100
  className="o-header__top-button--hide-m"
104
101
  />
105
102
  )}
106
- <MyFt className="" items={props.data?.account?.items} />
103
+ <MyFt className="" />
107
104
  </div>
108
105
  )
109
106
  }
@@ -165,7 +162,7 @@ const TopColumnRightAnon = ({ items, variant }: { items: TNavMenuItem[]; variant
165
162
  {signInAction && (
166
163
  <SignInLink item={signInAction} variant={variant} className="o-header__top-link--hide-m" />
167
164
  )}
168
- <MyFt className="o-header__top-icon-link--show-m" items={items} />
165
+ <MyFt className="o-header__top-icon-link--show-m" />
169
166
  </div>
170
167
  )
171
168
  }
@@ -175,8 +172,7 @@ const TopColumnRight = (props: THeaderProps) => {
175
172
  return <TopColumnRightLoggedIn {...props} />
176
173
  } else {
177
174
  const userNavAnonItems = props.data['navbar-right-anon'].items
178
- const userNavAccountItems = props.data.account?.items ?? []
179
- return <TopColumnRightAnon items={userNavAnonItems.concat(userNavAccountItems)} variant={props.variant} />
175
+ return <TopColumnRightAnon items={userNavAnonItems} variant={props.variant} />
180
176
  }
181
177
  }
182
178
 
package/src/index.tsx CHANGED
@@ -45,16 +45,10 @@ function MainHeader(props: THeaderProps) {
45
45
  {includeUserActionsNav ? <UserActionsNav {...props} /> : null}
46
46
  <TopWrapper>
47
47
  <TopColumnLeft />
48
- {props.showLogoLink ? (
49
- <TopColumnCenter url={props.data.editions?.current?.url} />
50
- ) : (
51
- <TopColumnCenterNoLink />
52
- )}
48
+ {props.showLogoLink ? <TopColumnCenter /> : <TopColumnCenterNoLink />}
53
49
  <TopColumnRight {...props} />
54
50
  </TopWrapper>
55
-
56
51
  <Search instance="primary" />
57
-
58
52
  <MobileNav {...props} />
59
53
  <NavDesktop>
60
54
  <NavListLeft {...props} />
@@ -116,13 +110,7 @@ function NoOutboundLinksHeader(props: THeaderProps) {
116
110
  return (
117
111
  <HeaderWrapper {...props}>
118
112
  {includeUserActionsNav ? <UserActionsNav {...props} /> : null}
119
- <TopWrapper>
120
- {props.showLogoLink ? (
121
- <TopColumnCenter url={props.data.editions?.current?.url} />
122
- ) : (
123
- <TopColumnCenterNoLink />
124
- )}
125
- </TopWrapper>
113
+ <TopWrapper>{props.showLogoLink ? <TopColumnCenter /> : <TopColumnCenterNoLink />}</TopWrapper>
126
114
  <NavDesktop>{props.showUserNavigation ? <NavListRight {...props} /> : null}</NavDesktop>
127
115
  {includeSubNavigation ? <SubNavigation {...props} /> : null}
128
116
  </HeaderWrapper>
package/styles.scss CHANGED
@@ -1,23 +1,14 @@
1
1
  // This will be overridden by dotcom-ui-layout, it's necessary here for storybook builds
2
2
  $system-code: 'page-kit-header' !default;
3
3
 
4
- @import 'n-ui-foundations/mixins';
4
+ @import "n-ui-foundations/mixins";
5
5
 
6
6
  // We don't need the sub-brand or transparent header styles so disable them.
7
7
  // TODO: move drawer styles into a separate stylesheet which can be lazy loaded?
8
- @import '@financial-times/o-header/main';
8
+ @import "@financial-times/o-header/main";
9
9
  @include oHeader(('top', 'nav', 'subnav', 'search', 'megamenu', 'drawer', 'anon', 'sticky', 'simple'));
10
10
 
11
- @import 'src/header';
11
+ @import "src/header";
12
12
 
13
- @import 'n-topic-search/main';
13
+ @import "n-topic-search/main";
14
14
  @include nTopicSearch;
15
-
16
- @import './src/enhanced-search/styles';
17
- @include enhancedSearch;
18
-
19
- @import '@financial-times/o-loading/main';
20
- @include oLoading();
21
-
22
- @import '@financial-times/o-message/main';
23
- @include oMessage();
@@ -1,170 +0,0 @@
1
- import BaseRenderer from 'n-topic-search/src/renderers/base-renderer'
2
-
3
- const DISPLAY_ITEMS = 5
4
-
5
- const headingMapping = {
6
- concepts: 'Related topics',
7
- equities: 'Securities'
8
- }
9
-
10
- class CustomSuggestionList extends BaseRenderer {
11
- constructor(container, options, enhancedSearchUrl) {
12
- super(container, options)
13
- this.renderSuggestionGroup = this.renderSuggestionGroup.bind(this)
14
- this.enhancedSearchUrl = enhancedSearchUrl
15
- this.createHtml()
16
- this.render()
17
- }
18
-
19
- renderSuggestionChip = (term) => {
20
- return `<a
21
- tabindex="0"
22
- data-trackable="link"
23
- data-suggestion-id="${term}"
24
- href="${this.enhancedSearchUrl}${term}"
25
- class="n-topic-search__target enhanced-search__chip">
26
- <span class="enhanced-search__chip-text">${term}</span>
27
- </a>`
28
- }
29
-
30
- renderDefaultSuggestionsChips() {
31
- return `
32
- <div class="enhanced-search__default-results">
33
- ${['Western support for Ukraine', 'How will AI be regulated?', 'UK inflation versus world']
34
- .map(this.renderSuggestionChip)
35
- .join('')}
36
- </div>`
37
- }
38
-
39
- renderSuggestionLink(suggestion, group) {
40
- return `<li class="n-topic-search__item">
41
- <a class="n-topic-search__target enhanced-search__target ${group.linkClassName}"
42
- href="${suggestion.url}"
43
- tabindex="0"
44
- data-trackable="link"
45
- data-suggestion-id="${suggestion.id}"
46
- data-suggestion-type="${suggestion.type}"
47
- >${suggestion.html}</a>
48
- </li>`
49
- }
50
-
51
- renderSuggestionGroup(group) {
52
- if (group.suggestions?.length || group.emptyHtml) {
53
- return `
54
- <div class="enhanced-search__group ${group.linkClassName}" data-trackable="${group.trackable}">
55
- <h3 class="enhanced-search__title">${group.heading}</h3>
56
- <ul class="n-topic-search__item-list">
57
- ${group.suggestions.map((suggestion) => this.renderSuggestionLink(suggestion, group)).join('')}
58
- </ul>
59
- </div>`
60
- }
61
- return ''
62
- }
63
-
64
- renderError() {
65
- return `
66
- <div
67
- class="o-message o-message--alert o-message--error enhanced-search__margin-top"
68
- data-o-component="o-message">
69
- <div class="o-message__container">
70
- <div class="o-message__content">
71
- <p class="o-message__content-main">Failed to load topics and securities results</p>
72
- </div>
73
- </div>
74
- </div>
75
- `
76
- }
77
-
78
- createHtml() {
79
- const term = this.state?.searchTerm
80
- const loading = this.state?.loading
81
- const error = this.state?.error !== undefined
82
- const hasConcepts = this.state?.suggestions?.concepts && this.state.suggestions.concepts.length
83
- const hasEquities = this.state?.suggestions?.equities && this.state.suggestions.equities.length
84
- const hasSuggestions = hasConcepts || hasEquities
85
- const suggestions = []
86
- this.items = []
87
- if (this.options.categories.includes('concepts')) {
88
- suggestions.push({
89
- heading: headingMapping['concepts'],
90
- linkClassName: 'enhanced-search__target--news',
91
- trackable: 'enhanced-search-news',
92
- suggestions: this.state.suggestions.concepts?.slice(0, DISPLAY_ITEMS).map((suggestion) => ({
93
- html: this.highlight(suggestion.prefLabel),
94
- url: suggestion.url,
95
- id: suggestion.id,
96
- type: 'enhanced-search-tag'
97
- }))
98
- })
99
- }
100
-
101
- if (this.options.categories.includes('equities')) {
102
- suggestions.push({
103
- heading: headingMapping['equities'],
104
- trackable: 'enhanced-search-equities',
105
- linkClassName: 'enhanced-search__target--equities',
106
- emptyHtml: '<div className="enhanced-search__no-results-message">No equities found</div>',
107
- suggestions: this.state.suggestions.equities?.slice(0, DISPLAY_ITEMS).map((suggestion) => ({
108
- html: `<span class="enhanced-search__target__equity-name">${this.highlight(
109
- suggestion.name
110
- )}</span><abbr>${this.highlight(suggestion.symbol)}</abbr>`,
111
- url: suggestion.url,
112
- id: suggestion.symbol,
113
- type: 'enhanced-search-equity'
114
- }))
115
- })
116
- }
117
-
118
- this.newHtml = `
119
- <div aria-live="assertive">
120
- ${
121
- hasSuggestions
122
- ? `
123
- <div
124
- class="o-normalise-visually-hidden n-topic-search__suggestions_explanation"
125
- >
126
- Search results have been displayed. To jump to the list of suggestions press
127
- the down arrow key.
128
- </div>
129
- `
130
- : ''
131
- }
132
- <div
133
- class="n-topic-search n-topic-search__suggestions enhanced-search enhanced-search__suggestions"
134
- data-trackable="typeahead"
135
- >
136
- <div class="enhanced-search__wrapper">
137
- <h3 class="enhanced-search__title">${
138
- term
139
- ? 'Get top results for...'
140
- : 'Search tip: <span class="enhanced-search__title-no-bold">Try using questions or phrases like...</span>'
141
- }</h3>
142
- ${term ? this.renderSuggestionChip(term) : this.renderDefaultSuggestionsChips()}
143
- <div class="o-normalise-visually-hidden">Suggestions include</div>
144
- ${error ? this.renderError() : ''}
145
- ${
146
- loading && !error
147
- ? `<div class="o-loading o-loading--dark o-loading--small enhanced-search__margin-top"></div>`
148
- : ''
149
- }
150
- ${
151
- hasSuggestions && term && !loading && !error
152
- ? `<div class="enhanced-search__suggestions-items">${suggestions
153
- .map(this.renderSuggestionGroup)
154
- .join('')}</div>
155
- `
156
- : ''
157
- }
158
- </div>
159
- </div>
160
- </div>`
161
- }
162
-
163
- handleSelection(el, ev) {
164
- ev.stopPropagation()
165
- // we don't prevent default as the link's url is a link to the relevant stream page
166
- return
167
- }
168
- }
169
-
170
- export default CustomSuggestionList
@@ -1,61 +0,0 @@
1
- import TopicSearch from 'n-topic-search'
2
- import CustomSuggestionList from './customList'
3
-
4
- class EnhancedSearch extends TopicSearch {
5
- constructor(containerEl, options) {
6
- super(containerEl, {
7
- ...options,
8
- listComponent: (...args) => new CustomSuggestionList(...args.concat(options?.enhancedSearchUrl)),
9
- errorCallback: (error) => {
10
- this.suggestionsView.setState({
11
- error,
12
- searchTerm: this.searchEl.value,
13
- suggestions: {}
14
- })
15
- // const detail = { category: 'search', action: `Error: ${error.message}` }
16
- // document.body.dispatchEvent(new CustomEvent('flyout-load-topics-error', { detail, bubbles: true }))
17
- }
18
- })
19
-
20
- this.updateEnhancedSearchAttributes(options)
21
- }
22
-
23
- updateEnhancedSearchAttributes(options) {
24
- const inputs = [
25
- document.querySelector('#o-header-search-term-primary'),
26
- document.querySelector('#o-header-search-term-sticky'),
27
- document.querySelector('#o-header-drawer-search-term')
28
- ]
29
-
30
- inputs.forEach((input, index) => {
31
- input.setAttribute('placeholder', 'Search for stories, topics or securities')
32
- input.parentElement.setAttribute('action', options?.enhancedSearchUrl ?? '/search')
33
-
34
- if (index === 0) input.parentElement.setAttribute('data-attribute-enhanced-search', 'true')
35
- })
36
-
37
- this.hide()
38
- }
39
-
40
- onFocus(ev) {
41
- super.onFocus(ev)
42
- this.show()
43
- this.suggestionTargets = Array.from(
44
- this.suggestionListContainer.querySelectorAll('.n-topic-search__target')
45
- )
46
- }
47
-
48
- onType(ev) {
49
- // This is to update the suggestion chip on keyup
50
- this.suggestionsView.setState({
51
- searchTerm: this.searchEl.value,
52
- loading: this.searchEl.value && this.searchEl.value.length >= this.minLength,
53
- suggestions: {}
54
- })
55
- super.onType(ev)
56
- // this is show the flyout for less than minimum length
57
- this.show()
58
- }
59
- }
60
-
61
- export default EnhancedSearch
@@ -1,152 +0,0 @@
1
- @use '@financial-times/o-colors/main' as colors;
2
- @use '@financial-times/o-spacing/main' as spacing;
3
- @use '@financial-times/o-typography/main' as typography;
4
-
5
- @mixin enhancedSearch {
6
- // Hide search-bar on small screens
7
- .o-header__search[aria-hidden='false'] {
8
- display: none;
9
- @include oGridRespondTo('L') {
10
- display: block;
11
- }
12
- }
13
-
14
- .enhanced-search {
15
- &__suggestions {
16
- @include oGridRespondTo('L') {
17
- max-width: 540px;
18
- left: calc(-1 * spacing.oSpacingByName('s3'));
19
- }
20
- }
21
-
22
- &__title {
23
- color: colors.oColorsByName('black');
24
- @include typography.oTypographySans($scale: 0, $style: 'normal', $weight: 'semibold');
25
- margin: 0 0 spacing.oSpacingByName('s3') 0;
26
- }
27
-
28
- &__title-no-bold {
29
- @include typography.oTypographySans($scale: 0, $style: 'normal', $weight: 'regular');
30
- }
31
-
32
- &__margin-top {
33
- margin-top: spacing.oSpacingByName('s4');
34
- }
35
-
36
- &__wrapper {
37
- display: flex;
38
- flex-direction: column;
39
- width: 100%;
40
- padding: spacing.oSpacingByName('s6');
41
- }
42
-
43
- &__title {
44
- color: colors.oColorsByName('black');
45
- @include typography.oTypographySans($scale: 0, $style: 'normal', $weight: 'semibold');
46
- margin: 0 0 spacing.oSpacingByName('s3') 0;
47
- }
48
-
49
- &__suggestions-items {
50
- display: flex;
51
- gap: spacing.oSpacingByName('m16');
52
- padding-top: spacing.oSpacingByName('s6');
53
- flex-direction: column;
54
-
55
- @include oGridRespondTo('L') {
56
- flex-direction: row;
57
- }
58
- }
59
-
60
- &__target {
61
- padding: 0;
62
- padding-block: spacing.oSpacingByName('s2');
63
- }
64
-
65
- &__target::before,
66
- &__chip::before {
67
- border-bottom: unset !important;
68
- }
69
-
70
- &__target:hover,
71
- &__target:focus {
72
- background-color: transparent;
73
- color: oColorsByName('teal');
74
- }
75
-
76
- &__target:hover:before,
77
- &__target:focus:before {
78
- opacity: 0;
79
- }
80
-
81
- &__target--news {
82
- min-width: spacing.oSpacingByIncrement(25);
83
- color: colors.oColorsByName('claret-70');
84
- }
85
-
86
- &__target--news:hover,
87
- &__target--news:focus {
88
- color: colors.oColorsByName('claret-30');
89
- }
90
-
91
- &__target--equities {
92
- color: colors.oColorsByName('black');
93
- }
94
-
95
- a.enhanced-search__target--equities{
96
- display: flex;
97
- align-items: flex-start;
98
- gap: spacing.oSpacingByName('s3');
99
- }
100
-
101
- &__target--equities:hover,
102
- &__target--equities:focus {
103
- color: colors.oColorsByName('slate');
104
- }
105
-
106
- &__chip {
107
- border-radius: spacing.oSpacingByName('s1');
108
- background: colors.oColorsMix('ft-grey', 'white', 10);
109
- padding: spacing.oSpacingByName('s2') spacing.oSpacingByName('s3');
110
- width: fit-content;
111
- cursor: pointer;
112
- text-decoration: none;
113
- display: block;
114
- overflow-wrap: anywhere;
115
- }
116
-
117
- &__chip:hover,
118
- &__chip:focus {
119
- background: colors.oColorsMix('ft-grey', 'white', 20);
120
- }
121
-
122
- &__chip:focus-visible {
123
- box-shadow: 0 0 0 spacing.oSpacingByIncrement(0.5) colors.oColorsByName('white'),
124
- 0 0 0 spacing.oSpacingByName('s1') colors.oColorsByName('black-70');
125
- color: colors.oColorsByName('white');
126
- border-color: transparent;
127
- border-radius: 0;
128
- outline: none;
129
- }
130
-
131
- &__chip-text {
132
- margin: 0;
133
- color: colors.oColorsByName('black');
134
- @include typography.oTypographySans($scale: -1, $style: 'normal', $weight: 'regular');
135
- outline: none;
136
- }
137
-
138
- &__default-results {
139
- display: flex;
140
- justify-content: flex-start;
141
- align-items: flex-start;
142
- gap: spacing.oSpacingByName('s2');
143
- flex-direction: column;
144
- flex-wrap: wrap;
145
-
146
- @include oGridRespondTo('L') {
147
- flex-direction: row;
148
- align-items: center;
149
- }
150
- }
151
- }
152
- }