@financial-times/dotcom-ui-header 10.0.1 → 10.1.0

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.
@@ -24,16 +24,6 @@ const Navigation = (props) => (react_1.default.createElement("div", { className:
24
24
  })))));
25
25
  const Logo = () => (react_1.default.createElement("a", { className: "o-header__top-logo o-header__hide--L", "data-trackable": "logo", href: "/", title: "Go to Financial Times homepage", tabIndex: -1 },
26
26
  react_1.default.createElement("span", { className: "o-header__visually-hidden" }, "Financial Times")));
27
- const NavListRightAnonSticky = (props) => {
28
- // If user is anonymous the second list item is styled as a button
29
- const [signInAction, subscribeAction] = props.data['navbar-right-anon'].items;
30
- return (react_1.default.createElement("div", { className: "o-header__nav" },
31
- react_1.default.createElement("div", { className: "o-header__top-column o-header__top-column--right" },
32
- subscribeAction && (react_1.default.createElement(partials_1.SubscribeButton, { item: subscribeAction, variant: "sticky", className: "o-header__top-button--hide-m" })),
33
- signInAction && react_1.default.createElement(partials_1.SignInLink, { item: signInAction, variant: "sticky", className: "" }))));
34
- };
35
- 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 },
36
- react_1.default.createElement("span", { className: "o-header__visually-hidden" }, "myFT")));
37
27
  const TopWrapperSticky = (props) => (react_1.default.createElement("div", { className: "o-header__row o-header__top", "data-trackable": "header-sticky" },
38
28
  react_1.default.createElement("div", { className: "o-header__container" },
39
29
  react_1.default.createElement("div", { className: "o-header__top-wrapper" }, props.children))));
@@ -51,24 +41,7 @@ const TopColumnCenterSticky = (props) => {
51
41
  react_1.default.createElement(Logo, null)));
52
42
  };
53
43
  exports.TopColumnCenterSticky = TopColumnCenterSticky;
54
- const NavListRightLoggedInSticky = (props) => {
55
- var _a;
56
- const subscribeAction = (_a = props.data['navbar-right-anon'].items) === null || _a === void 0 ? void 0 : _a[1];
57
- return (react_1.default.createElement(react_1.default.Fragment, null,
58
- !props.userIsSubscribed && subscribeAction && (react_1.default.createElement(partials_1.SubscribeButton, { item: subscribeAction, variant: "sticky", className: "o-header__top-button--hide-m" })),
59
- react_1.default.createElement(MyFtSticky, { className: "" })));
60
- };
61
- // This behaviour is similar to `NavListRight` in '../navigation/partials' but:
62
- // - The sticky header renders either the `navbar-right-anon` data or the myFT component
63
- // - The normal header renders either the `navbar-right-anon` or the `navbar-right` data
64
44
  const TopColumnRightSticky = (props) => {
65
- let children = undefined;
66
- if (props.userIsLoggedIn) {
67
- children = react_1.default.createElement(NavListRightLoggedInSticky, Object.assign({}, props));
68
- }
69
- else if (props.showUserNavigation) {
70
- children = react_1.default.createElement(NavListRightAnonSticky, Object.assign({}, props));
71
- }
72
- return react_1.default.createElement("div", { className: "o-header__top-column o-header__top-column--right" }, children);
45
+ return react_1.default.createElement(partials_1.TopColumnRight, Object.assign({}, props));
73
46
  };
74
47
  exports.TopColumnRightSticky = TopColumnRightSticky;
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { THeaderProps } from '../../interfaces';
2
+ import { THeaderProps, THeaderVariant } from '../../interfaces';
3
3
  import { TNavMenuItem } from '@financial-times/dotcom-types-navigation';
4
4
  declare const HeaderWrapper: (props: any) => React.JSX.Element;
5
5
  declare const TopWrapper: (props: any) => React.JSX.Element;
@@ -8,17 +8,17 @@ declare const TopColumnCenter: () => React.JSX.Element;
8
8
  declare const TopColumnCenterNoLink: () => React.JSX.Element;
9
9
  declare const SignInLink: ({ item, variant, className }: {
10
10
  item: TNavMenuItem;
11
- variant?: string | undefined;
11
+ variant?: "simple" | "large-logo" | "sticky" | undefined;
12
12
  className?: string | undefined;
13
13
  }) => React.JSX.Element;
14
14
  declare const SubscribeButton: ({ item, variant, className }: {
15
15
  item: TNavMenuItem;
16
- variant?: string | undefined;
16
+ variant?: "simple" | "large-logo" | "sticky" | undefined;
17
17
  className?: string | undefined;
18
18
  }) => React.JSX.Element;
19
19
  declare const TopColumnRightAnon: ({ items, variant }: {
20
20
  items: TNavMenuItem[];
21
- variant?: string | undefined;
21
+ variant?: "simple" | "large-logo" | "sticky" | undefined;
22
22
  }) => React.JSX.Element;
23
23
  declare const TopColumnRight: (props: THeaderProps) => React.JSX.Element;
24
24
  export { HeaderWrapper, TopWrapper, TopColumnLeft, TopColumnCenter, TopColumnCenterNoLink, TopColumnRight, TopColumnRightAnon, SubscribeButton, SignInLink };
@@ -13,10 +13,11 @@ const DrawerIcon = () => (react_1.default.createElement("a", { href: "#o-header-
13
13
  react_1.default.createElement("span", { className: "o-header__top-link-label" }, "Open side navigation menu")));
14
14
  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" },
15
15
  react_1.default.createElement("span", { className: "o-header__top-link-label" }, "Open search bar")));
16
- const MyAccountLink = ({ item, signedIn }) => {
16
+ const MyAccountLink = ({ item, signedIn, variant }) => {
17
17
  const classNames = 'o-header__top-myaccount';
18
18
  const id = signedIn ? 'o-header-top-link-myaccount' : 'o-header-top-link-signin';
19
- return (react_1.default.createElement("a", { className: classNames, id: id, href: item.url || undefined, "data-trackable": item.label },
19
+ const setTabIndex = variant === 'sticky' ? { tabIndex: -1 } : null;
20
+ return (react_1.default.createElement("a", Object.assign({ className: classNames, id: id, href: item.url || undefined, "data-trackable": item.label }, setTabIndex),
20
21
  react_1.default.createElement("span", null, item.label)));
21
22
  };
22
23
  const TopWrapper = (props) => (react_1.default.createElement("div", { className: "o-header__row o-header__top", "data-trackable": "header-top" },
@@ -42,7 +43,7 @@ const TopColumnRightLoggedIn = (props) => {
42
43
  const subscribeAction = (_d = (_c = props.data['navbar-top-right']) === null || _c === void 0 ? void 0 : _c.items) === null || _d === void 0 ? void 0 : _d[1];
43
44
  return (react_1.default.createElement("div", { className: "o-header__top-column o-header__top-column--right" },
44
45
  !props.userIsSubscribed && subscribeAction && (react_1.default.createElement(SubscribeButton, { item: subscribeAction, variant: props.variant, className: "o-header__top-button--hide-m" })),
45
- signInAction && react_1.default.createElement(MyAccountLink, { item: signInAction, signedIn: true })));
46
+ signInAction && react_1.default.createElement(MyAccountLink, { item: signInAction, signedIn: true, variant: props.variant })));
46
47
  };
47
48
  const SignInLink = ({ item, variant, className }) => {
48
49
  var _a;
@@ -4,7 +4,7 @@ declare function MainHeader(props: THeaderProps): React.JSX.Element;
4
4
  declare namespace MainHeader {
5
5
  var defaultProps: {
6
6
  showLogoLink: boolean;
7
- variant?: "simple" | "large-logo" | undefined;
7
+ variant?: "simple" | "large-logo" | "sticky" | undefined;
8
8
  userIsAnonymous?: boolean | undefined;
9
9
  userIsLoggedIn?: boolean | undefined;
10
10
  userIsSubscribed?: boolean | undefined;
@@ -39,11 +39,15 @@ function MainHeader(props) {
39
39
  exports.MainHeader = MainHeader;
40
40
  MainHeader.defaultProps = { ...defaultProps, showLogoLink: true };
41
41
  function StickyHeader(props) {
42
- return props.showStickyHeader ? (react_1.default.createElement(partials_3.StickyHeaderWrapper, Object.assign({}, props),
42
+ const stickyProps = {
43
+ ...props,
44
+ variant: 'sticky'
45
+ };
46
+ return props.showStickyHeader ? (react_1.default.createElement(partials_3.StickyHeaderWrapper, Object.assign({}, stickyProps),
43
47
  react_1.default.createElement(partials_3.TopWrapperSticky, null,
44
- react_1.default.createElement(partials_3.TopColumnLeftSticky, Object.assign({}, props)),
45
- react_1.default.createElement(partials_3.TopColumnCenterSticky, Object.assign({}, props)),
46
- react_1.default.createElement(partials_3.TopColumnRightSticky, Object.assign({}, props))),
48
+ react_1.default.createElement(partials_3.TopColumnLeftSticky, Object.assign({}, stickyProps)),
49
+ react_1.default.createElement(partials_3.TopColumnCenterSticky, Object.assign({}, stickyProps)),
50
+ react_1.default.createElement(partials_3.TopColumnRightSticky, Object.assign({}, stickyProps))),
47
51
  react_1.default.createElement(partials_5.Search, { instance: "sticky" }))) : null;
48
52
  }
49
53
  exports.StickyHeader = StickyHeader;
@@ -172,8 +172,8 @@
172
172
  "affectsGlobalScope": false
173
173
  },
174
174
  "../src/interfaces.d.ts": {
175
- "version": "2fe58268385c91140d66300355fc27cb349306472adcac6a09fb484dc974a191",
176
- "signature": "2fe58268385c91140d66300355fc27cb349306472adcac6a09fb484dc974a191",
175
+ "version": "cbe4ccd33266355f4049ecb96003c7e1f4c382952523c4a53bf9a575c0f9f6a0",
176
+ "signature": "cbe4ccd33266355f4049ecb96003c7e1f4c382952523c4a53bf9a575c0f9f6a0",
177
177
  "affectsGlobalScope": false
178
178
  },
179
179
  "../src/components/svg-components/BrandFtMasthead.tsx": {
@@ -187,8 +187,8 @@
187
187
  "affectsGlobalScope": false
188
188
  },
189
189
  "../src/components/top/partials.tsx": {
190
- "version": "6e068efc8dd9cf189851596ea98000f6299a910dfd4c4da49ac9f7d5f4fb3001",
191
- "signature": "52e9ca0196757edb87416ec63a0da3f2f6963cb4ca1fab821e487cf42fd0b4cf",
190
+ "version": "f40214092408dfe8a12e842668caa94faecb31b460d015e34567e5dcc1445307",
191
+ "signature": "76906372a1b286f93aa80f146a97782d3fa965ceb5e5314d8ae9da20ac3aa28c",
192
192
  "affectsGlobalScope": false
193
193
  },
194
194
  "../src/utils.ts": {
@@ -202,7 +202,7 @@
202
202
  "affectsGlobalScope": false
203
203
  },
204
204
  "../src/components/sticky/partials.tsx": {
205
- "version": "9a0b683328c80d151d0b70b516597dbb365dd3f44ccb08fbd78a9c1509475ba9",
205
+ "version": "77aadd42305d77b0692de540e5ecde571dbcae237489a2631a874f5bbcead2b6",
206
206
  "signature": "8fbeb8e68c5be0e2f41a60731bb91f6c54327ecca0d18857c3feeaa06e1cd389",
207
207
  "affectsGlobalScope": false
208
208
  },
@@ -227,8 +227,8 @@
227
227
  "affectsGlobalScope": false
228
228
  },
229
229
  "../src/index.tsx": {
230
- "version": "1590223c256c5d68b425be24b35676fdefdb9460dac8c04b7e6fbe4c9ce82477",
231
- "signature": "09d351582aa153eefd5469b12224f3eb0306b746105e502d1eb609bb871a1b7e",
230
+ "version": "48b3d98dfe3794304df0358bf64bdf774456afd1357c94ac916e06b6e69dfbf5",
231
+ "signature": "266fc48b55086f153414fd941015aac22cf08511c95a062d058e970537fce334",
232
232
  "affectsGlobalScope": false
233
233
  },
234
234
  "../../../node_modules/@types/aria-query/index.d.ts": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@financial-times/dotcom-ui-header",
3
- "version": "10.0.1",
3
+ "version": "10.1.0",
4
4
  "description": "",
5
5
  "browser": "browser.js",
6
6
  "main": "component.js",
@@ -22,7 +22,7 @@
22
22
  "author": "",
23
23
  "license": "MIT",
24
24
  "dependencies": {
25
- "@financial-times/dotcom-types-navigation": "^10.0.1",
25
+ "@financial-times/dotcom-types-navigation": "^10.1.0",
26
26
  "n-topic-search": "^4.0.0"
27
27
  },
28
28
  "devDependencies": {
@@ -235,15 +235,14 @@ exports[`dotcom-ui-header/src/components/StickyHeader renders ASK FT button 1`]
235
235
  Subscribe
236
236
  </a>
237
237
  <a
238
- className="o-header__top-icon-link o-header__top-icon-link--myft "
239
- data-trackable="my-ft"
240
- href="/myft"
238
+ className="o-header__top-myaccount"
239
+ data-trackable="My Account"
240
+ href="/myaccount"
241
+ id="o-header-top-link-myaccount"
241
242
  tabIndex={-1}
242
243
  >
243
- <span
244
- className="o-header__visually-hidden"
245
- >
246
- myFT
244
+ <span>
245
+ My Account
247
246
  </span>
248
247
  </a>
249
248
  </div>
@@ -540,15 +539,14 @@ exports[`dotcom-ui-header/src/components/StickyHeader renders as a logged in use
540
539
  Subscribe
541
540
  </a>
542
541
  <a
543
- className="o-header__top-icon-link o-header__top-icon-link--myft "
544
- data-trackable="my-ft"
545
- href="/myft"
542
+ className="o-header__top-myaccount"
543
+ data-trackable="My Account"
544
+ href="/myaccount"
545
+ id="o-header-top-link-myaccount"
546
546
  tabIndex={-1}
547
547
  >
548
- <span
549
- className="o-header__visually-hidden"
550
- >
551
- myFT
548
+ <span>
549
+ My Account
552
550
  </span>
553
551
  </a>
554
552
  </div>
@@ -834,7 +832,27 @@ exports[`dotcom-ui-header/src/components/StickyHeader renders as an anonymous us
834
832
  </div>
835
833
  <div
836
834
  className="o-header__top-column o-header__top-column--right"
837
- />
835
+ >
836
+ <a
837
+ className="o-header__top-button o-header__top-button--hide-m"
838
+ data-trackable="Subscribe"
839
+ href="/products?segmentId=#"
840
+ role="button"
841
+ tabIndex={-1}
842
+ >
843
+ Subscribe
844
+ </a>
845
+ <a
846
+ className="o-header__top-myaccount"
847
+ data-trackable="Sign In"
848
+ href="/login?location=#"
849
+ id="o-header-top-link-signin"
850
+ >
851
+ <span>
852
+ Sign In
853
+ </span>
854
+ </a>
855
+ </div>
838
856
  </div>
839
857
  </div>
840
858
  </div>
@@ -95,12 +95,12 @@ describe('dotcom-ui-header', () => {
95
95
 
96
96
  expect(
97
97
  container.querySelector(
98
- '.o-header__top-column .o-header__top-column--right a[data-trackable="Subscribe"]'
98
+ '.o-header__top-column.o-header__top-column--right a[data-trackable="Subscribe"]'
99
99
  )
100
100
  ).not.toBeNull()
101
101
  expect(
102
102
  container.querySelector(
103
- '.o-header__top-column .o-header__top-column--right a[data-trackable="Sign In"]'
103
+ '.o-header__top-column.o-header__top-column--right a[data-trackable="Sign In"]'
104
104
  )
105
105
  ).not.toBeNull()
106
106
  })
@@ -2,7 +2,7 @@
2
2
  /* This is the sticky header variant */
3
3
 
4
4
  import React from 'react'
5
- import { SubscribeButton, SignInLink } from '../top/partials'
5
+ import { TopColumnRight } from '../top/partials'
6
6
  import { THeaderProps } from '../../interfaces'
7
7
  import { AskFtButton } from '../ask-ft/askFtButton'
8
8
 
@@ -74,32 +74,6 @@ const Logo = () => (
74
74
  </a>
75
75
  )
76
76
 
77
- const NavListRightAnonSticky = (props: THeaderProps) => {
78
- // If user is anonymous the second list item is styled as a button
79
- const [signInAction, subscribeAction] = props.data['navbar-right-anon'].items
80
- return (
81
- <div className="o-header__nav">
82
- <div className="o-header__top-column o-header__top-column--right">
83
- {subscribeAction && (
84
- <SubscribeButton item={subscribeAction} variant="sticky" className="o-header__top-button--hide-m" />
85
- )}
86
- {signInAction && <SignInLink item={signInAction} variant="sticky" className="" />}
87
- </div>
88
- </div>
89
- )
90
- }
91
-
92
- const MyFtSticky = ({ className }: { className?: string }) => (
93
- <a
94
- className={`o-header__top-icon-link o-header__top-icon-link--myft ${className}`}
95
- href="/myft"
96
- data-trackable="my-ft"
97
- tabIndex={-1}
98
- >
99
- <span className="o-header__visually-hidden">myFT</span>
100
- </a>
101
- )
102
-
103
77
  const TopWrapperSticky = (props) => (
104
78
  <div className="o-header__row o-header__top" data-trackable="header-sticky">
105
79
  <div className="o-header__container">
@@ -132,31 +106,8 @@ const TopColumnCenterSticky = (props: THeaderProps) => {
132
106
  )
133
107
  }
134
108
 
135
- const NavListRightLoggedInSticky = (props: THeaderProps) => {
136
- const subscribeAction = props.data['navbar-right-anon'].items?.[1]
137
- return (
138
- <React.Fragment>
139
- {!props.userIsSubscribed && subscribeAction && (
140
- <SubscribeButton item={subscribeAction} variant="sticky" className="o-header__top-button--hide-m" />
141
- )}
142
- <MyFtSticky className="" />
143
- </React.Fragment>
144
- )
145
- }
146
-
147
- // This behaviour is similar to `NavListRight` in '../navigation/partials' but:
148
- // - The sticky header renders either the `navbar-right-anon` data or the myFT component
149
- // - The normal header renders either the `navbar-right-anon` or the `navbar-right` data
150
109
  const TopColumnRightSticky = (props: THeaderProps) => {
151
- let children: JSX.Element | undefined = undefined
152
-
153
- if (props.userIsLoggedIn) {
154
- children = <NavListRightLoggedInSticky {...props} />
155
- } else if (props.showUserNavigation) {
156
- children = <NavListRightAnonSticky {...props} />
157
- }
158
-
159
- return <div className="o-header__top-column o-header__top-column--right">{children}</div>
110
+ return <TopColumnRight {...props} />
160
111
  }
161
112
 
162
113
  export {
@@ -1,5 +1,5 @@
1
1
  import React from 'react'
2
- import { THeaderProps } from '../../interfaces'
2
+ import { THeaderProps, THeaderVariant } from '../../interfaces'
3
3
  import BrandFtMastheadSvg from '../svg-components/BrandFtMasthead'
4
4
  import { TNavMenuItem } from '@financial-times/dotcom-types-navigation'
5
5
  import { AskFtButton } from '../ask-ft/askFtButton'
@@ -40,12 +40,27 @@ const SearchIcon = () => (
40
40
  </a>
41
41
  )
42
42
 
43
- const MyAccountLink = ({ item, signedIn }: { item: TNavMenuItem; signedIn: boolean }) => {
43
+ const MyAccountLink = ({
44
+ item,
45
+ signedIn,
46
+ variant
47
+ }: {
48
+ item: TNavMenuItem
49
+ signedIn: boolean
50
+ variant?: THeaderVariant
51
+ }) => {
44
52
  const classNames = 'o-header__top-myaccount'
45
53
  const id = signedIn ? 'o-header-top-link-myaccount' : 'o-header-top-link-signin'
54
+ const setTabIndex = variant === 'sticky' ? { tabIndex: -1 } : null
46
55
 
47
56
  return (
48
- <a className={classNames} id={id} href={item.url || undefined} data-trackable={item.label}>
57
+ <a
58
+ className={classNames}
59
+ id={id}
60
+ href={item.url || undefined}
61
+ data-trackable={item.label}
62
+ {...setTabIndex}
63
+ >
49
64
  <span>{item.label}</span>
50
65
  </a>
51
66
  )
@@ -107,7 +122,7 @@ const TopColumnRightLoggedIn = (props: THeaderProps) => {
107
122
  className="o-header__top-button--hide-m"
108
123
  />
109
124
  )}
110
- {signInAction && <MyAccountLink item={signInAction} signedIn={true} />}
125
+ {signInAction && <MyAccountLink item={signInAction} signedIn={true} variant={props.variant} />}
111
126
  </div>
112
127
  )
113
128
  }
@@ -118,7 +133,7 @@ const SignInLink = ({
118
133
  className
119
134
  }: {
120
135
  item: TNavMenuItem
121
- variant?: string
136
+ variant?: THeaderVariant
122
137
  className?: string
123
138
  }) => {
124
139
  const setTabIndex = variant === 'sticky' ? { tabIndex: -1 } : null
@@ -139,7 +154,7 @@ const SubscribeButton = ({
139
154
  className
140
155
  }: {
141
156
  item: TNavMenuItem
142
- variant?: string
157
+ variant?: THeaderVariant
143
158
  className?: string
144
159
  }) => {
145
160
  const setTabIndex = variant === 'sticky' ? { tabIndex: -1 } : null
@@ -158,7 +173,7 @@ const SubscribeButton = ({
158
173
  )
159
174
  }
160
175
 
161
- const TopColumnRightAnon = ({ items, variant }: { items: TNavMenuItem[]; variant?: string }) => {
176
+ const TopColumnRightAnon = ({ items, variant }: { items: TNavMenuItem[]; variant?: THeaderVariant }) => {
162
177
  // If user is anonymous the second list item is styled as a button
163
178
  const [signInAction, subscribeAction] = items
164
179
 
package/src/index.tsx CHANGED
@@ -25,7 +25,7 @@ import { SubNavigation } from './components/sub-navigation/partials'
25
25
  import { IncludeDrawer } from './components/drawer/topLevelPartials'
26
26
  import { Search } from './components/search/partials'
27
27
 
28
- import { THeaderProps, THeaderOptions } from './interfaces'
28
+ import { THeaderProps, THeaderOptions, THeaderVariant } from './interfaces'
29
29
 
30
30
  const defaultProps: Partial<THeaderOptions> = {
31
31
  showSubNavigation: true,
@@ -63,12 +63,17 @@ function MainHeader(props: THeaderProps) {
63
63
  MainHeader.defaultProps = { ...defaultProps, showLogoLink: true }
64
64
 
65
65
  function StickyHeader(props: THeaderProps) {
66
+ const stickyProps = {
67
+ ...props,
68
+ variant: 'sticky' as THeaderVariant
69
+ }
70
+
66
71
  return props.showStickyHeader ? (
67
- <StickyHeaderWrapper {...props}>
72
+ <StickyHeaderWrapper {...stickyProps}>
68
73
  <TopWrapperSticky>
69
- <TopColumnLeftSticky {...props} />
70
- <TopColumnCenterSticky {...props} />
71
- <TopColumnRightSticky {...props} />
74
+ <TopColumnLeftSticky {...stickyProps} />
75
+ <TopColumnCenterSticky {...stickyProps} />
76
+ <TopColumnRightSticky {...stickyProps} />
72
77
  </TopWrapperSticky>
73
78
  <Search instance="sticky" />
74
79
  </StickyHeaderWrapper>
@@ -17,4 +17,4 @@ export type THeaderProps = THeaderOptions & {
17
17
  data: TNavigationData
18
18
  }
19
19
 
20
- export type THeaderVariant = 'simple' | 'large-logo'
20
+ export type THeaderVariant = 'simple' | 'large-logo' | 'sticky'