@financial-times/dotcom-ui-header 13.1.0 → 13.2.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.
@@ -1568,3 +1568,333 @@ exports[`dotcom-ui-header/src/components/StickyHeader renders as an anonymous us
1568
1568
  </div>
1569
1569
  </header>
1570
1570
  `;
1571
+
1572
+ exports[`dotcom-ui-header/src/components/StickyHeader renders restart subscription button when showRestartSubscriptionButton is true 1`] = `
1573
+ <header
1574
+ aria-hidden="true"
1575
+ className="o-header o-header--simple o-header--sticky o--if-js"
1576
+ data-o-component="o-header"
1577
+ data-o-header--sticky={true}
1578
+ >
1579
+ <div
1580
+ className="o-header__row o-header__top"
1581
+ data-trackable="header-sticky"
1582
+ >
1583
+ <div
1584
+ className="o-header__container"
1585
+ >
1586
+ <div
1587
+ className="o-header__top-wrapper"
1588
+ >
1589
+ <div
1590
+ className="o-header__top-column o-header__top-column--left"
1591
+ >
1592
+ <a
1593
+ aria-controls="o-header-drawer"
1594
+ className="o-header__top-icon-link o-header__top-icon-link--menu"
1595
+ data-trackable="drawer-toggle"
1596
+ href="#"
1597
+ tabIndex={-1}
1598
+ >
1599
+ <span
1600
+ className="o-header__top-link-label"
1601
+ >
1602
+ Menu
1603
+ </span>
1604
+ </a>
1605
+ <a
1606
+ aria-controls="o-header-search-sticky"
1607
+ className="o-header__top-icon-link o-header__top-icon-link--search"
1608
+ data-trackable="search-toggle"
1609
+ href="#"
1610
+ tabIndex={-1}
1611
+ >
1612
+ <span
1613
+ className="o-header__top-link-label"
1614
+ >
1615
+ Search
1616
+ </span>
1617
+ </a>
1618
+ </div>
1619
+ <div
1620
+ className="o-header__top-column o-header__top-column--center"
1621
+ >
1622
+ <div
1623
+ className="o-header__top-takeover"
1624
+ >
1625
+ <div
1626
+ className="o-header__nav"
1627
+ >
1628
+ <ul
1629
+ className="o-header__nav-list o-header__nav-list--left"
1630
+ data-trackable="primary-nav"
1631
+ >
1632
+ <li
1633
+ className="o-header__nav-item"
1634
+ >
1635
+ <a
1636
+ className="o-header__nav-link o-header__nav-link--primary"
1637
+ data-trackable="Home"
1638
+ href="/"
1639
+ tabIndex={-1}
1640
+ >
1641
+ Home
1642
+ </a>
1643
+ </li>
1644
+ <li
1645
+ className="o-header__nav-item"
1646
+ >
1647
+ <a
1648
+ className="o-header__nav-link o-header__nav-link--primary"
1649
+ data-trackable="World"
1650
+ href="/world"
1651
+ tabIndex={-1}
1652
+ >
1653
+ World
1654
+ </a>
1655
+ </li>
1656
+ <li
1657
+ className="o-header__nav-item"
1658
+ >
1659
+ <a
1660
+ className="o-header__nav-link o-header__nav-link--primary"
1661
+ data-trackable="UK"
1662
+ href="/world/uk"
1663
+ tabIndex={-1}
1664
+ >
1665
+ UK
1666
+ </a>
1667
+ </li>
1668
+ <li
1669
+ className="o-header__nav-item"
1670
+ >
1671
+ <a
1672
+ className="o-header__nav-link o-header__nav-link--primary"
1673
+ data-trackable="Companies"
1674
+ href="/companies"
1675
+ tabIndex={-1}
1676
+ >
1677
+ Companies
1678
+ </a>
1679
+ </li>
1680
+ <li
1681
+ className="o-header__nav-item"
1682
+ >
1683
+ <a
1684
+ className="o-header__nav-link o-header__nav-link--primary"
1685
+ data-trackable="Tech"
1686
+ href="/technology"
1687
+ tabIndex={-1}
1688
+ >
1689
+ Tech
1690
+ </a>
1691
+ </li>
1692
+ <li
1693
+ className="o-header__nav-item"
1694
+ >
1695
+ <a
1696
+ className="o-header__nav-link o-header__nav-link--primary"
1697
+ data-trackable="Markets"
1698
+ href="/markets"
1699
+ tabIndex={-1}
1700
+ >
1701
+ Markets
1702
+ </a>
1703
+ </li>
1704
+ <li
1705
+ className="o-header__nav-item"
1706
+ >
1707
+ <a
1708
+ className="o-header__nav-link o-header__nav-link--primary"
1709
+ data-trackable="Graphics"
1710
+ href="/graphics"
1711
+ tabIndex={-1}
1712
+ >
1713
+ Graphics
1714
+ </a>
1715
+ </li>
1716
+ <li
1717
+ className="o-header__nav-item"
1718
+ >
1719
+ <a
1720
+ className="o-header__nav-link o-header__nav-link--primary"
1721
+ data-trackable="Opinion"
1722
+ href="/opinion"
1723
+ tabIndex={-1}
1724
+ >
1725
+ Opinion
1726
+ </a>
1727
+ </li>
1728
+ <li
1729
+ className="o-header__nav-item"
1730
+ >
1731
+ <a
1732
+ className="o-header__nav-link o-header__nav-link--primary"
1733
+ data-trackable="Work & Careers"
1734
+ href="/work-careers"
1735
+ tabIndex={-1}
1736
+ >
1737
+ Work & Careers
1738
+ </a>
1739
+ </li>
1740
+ <li
1741
+ className="o-header__nav-item"
1742
+ >
1743
+ <a
1744
+ className="o-header__nav-link o-header__nav-link--primary"
1745
+ data-trackable="Life & Arts"
1746
+ href="/life-arts"
1747
+ tabIndex={-1}
1748
+ >
1749
+ Life & Arts
1750
+ </a>
1751
+ </li>
1752
+ <li
1753
+ className="o-header__nav-item"
1754
+ >
1755
+ <a
1756
+ className="o-header__nav-link o-header__nav-link--primary"
1757
+ data-trackable="HTSI"
1758
+ href="https://howtospendit.ft.com/"
1759
+ tabIndex={-1}
1760
+ >
1761
+ HTSI
1762
+ </a>
1763
+ </li>
1764
+ </ul>
1765
+ </div>
1766
+ </div>
1767
+ <a
1768
+ className="o-header__top-logo o-header__hide--L"
1769
+ data-trackable="logo"
1770
+ href="/"
1771
+ tabIndex={-1}
1772
+ title="Go to Financial Times homepage"
1773
+ >
1774
+ <span
1775
+ className="o-header__visually-hidden"
1776
+ >
1777
+ Financial Times
1778
+ </span>
1779
+ </a>
1780
+ </div>
1781
+ <div
1782
+ className="o-header__top-column o-header__top-column--right"
1783
+ >
1784
+ <a
1785
+ className="o-header__top-button o3-button o3-button--primary"
1786
+ data-trackable="Restart Subscription"
1787
+ href="/myaccount/subscription"
1788
+ role="button"
1789
+ tabIndex={-1}
1790
+ >
1791
+ Restart Subscription
1792
+ </a>
1793
+ <a
1794
+ className="o-header__top-button o-header__top-button--hide-m"
1795
+ data-trackable="Subscribe"
1796
+ href="/products?segmentId=#"
1797
+ role="button"
1798
+ tabIndex={-1}
1799
+ >
1800
+ Subscribe
1801
+ </a>
1802
+ <a
1803
+ className="o-header__top-myaccount"
1804
+ data-trackable="My Account"
1805
+ href="/myaccount"
1806
+ id="o-header-top-link-myaccount"
1807
+ tabIndex={-1}
1808
+ >
1809
+ <span>
1810
+ My Account
1811
+ </span>
1812
+ </a>
1813
+ </div>
1814
+ </div>
1815
+ </div>
1816
+ </div>
1817
+ <div
1818
+ className="o-header__row o-header__search o-header__search--sticky"
1819
+ data-o-header-search={true}
1820
+ data-trackable="header-search"
1821
+ id="o-header-search-sticky"
1822
+ >
1823
+ <div
1824
+ className="o-header__container"
1825
+ >
1826
+ <form
1827
+ action="/search"
1828
+ aria-label="Site search"
1829
+ className="o-header__search-form"
1830
+ data-n-topic-search={true}
1831
+ role="search"
1832
+ >
1833
+ <label
1834
+ className="o-header__search-term o-forms-field o-forms-field--optional"
1835
+ htmlFor="o-header-search-term-sticky"
1836
+ >
1837
+ <span
1838
+ className="o-forms-title o-header__visually-hidden"
1839
+ >
1840
+ <span
1841
+ className="o-forms-title__main"
1842
+ >
1843
+ Search the
1844
+ <abbr
1845
+ title="Financial Times"
1846
+ >
1847
+ FT
1848
+ </abbr>
1849
+ </span>
1850
+ </span>
1851
+ <span
1852
+ className="o-forms-input o-forms-input--text o-forms-input--suffix"
1853
+ >
1854
+ <input
1855
+ aria-controls="suggestions-o-header-search-term-sticky"
1856
+ autoCapitalize="off"
1857
+ autoComplete="off"
1858
+ autoCorrect="off"
1859
+ id="o-header-search-term-sticky"
1860
+ name="q"
1861
+ placeholder="Search for stories, topics or securities"
1862
+ role="combobox"
1863
+ spellCheck={false}
1864
+ type="search"
1865
+ />
1866
+ <button
1867
+ className="o-header__search-submit"
1868
+ type="submit"
1869
+ >
1870
+ <span
1871
+ aria-hidden="true"
1872
+ className="o-header__search-icon"
1873
+ />
1874
+ <span>
1875
+ Search
1876
+ </span>
1877
+ </button>
1878
+ <button
1879
+ aria-controls="o-header-search-sticky"
1880
+ className="o-header__search-close o--if-js"
1881
+ data-trackable="close"
1882
+ title="Close search bar"
1883
+ type="button"
1884
+ >
1885
+ <span
1886
+ className="o-header__visually-hidden"
1887
+ >
1888
+ Close search bar
1889
+ </span>
1890
+ <span>
1891
+ Close
1892
+ </span>
1893
+ </button>
1894
+ </span>
1895
+ </label>
1896
+ </form>
1897
+ </div>
1898
+ </div>
1899
+ </header>
1900
+ `;
@@ -12,6 +12,11 @@ const data: TNavMenu = {
12
12
  label: 'Subscribe',
13
13
  url: '/products?segmentId=#',
14
14
  submenu: null
15
+ },
16
+ {
17
+ label: 'Restart Subscription',
18
+ url: '/myaccount/subscription',
19
+ submenu: null
15
20
  }
16
21
  ]
17
22
  }
@@ -12,18 +12,30 @@ const headerFixture = {
12
12
  ...dataFixture,
13
13
  data: { ...dataFixture.data, currentPath: '/' }
14
14
  }
15
- const subscribedUserFixture = { ...dataFixture, showUserNavigation: true, userIsSubscribed: true }
16
- const loggedInUserFixture = { ...dataFixture, showUserNavigation: true }
15
+ const subscribedUserFixture = {
16
+ ...dataFixture,
17
+ showUserNavigation: true,
18
+ userIsSubscribed: true,
19
+ showRestartSubscriptionButton: true
20
+ }
21
+ const loggedInUserFixture = { ...dataFixture, showUserNavigation: true, showRestartSubscriptionButton: true }
22
+ const loggedInUserWithoutRestartFixture = {
23
+ ...dataFixture,
24
+ showUserNavigation: true,
25
+ showRestartSubscriptionButton: false
26
+ }
17
27
  const anonymousUserFixture = {
18
28
  ...dataFixture,
19
29
  userIsAnonymous: true,
20
30
  userIsLoggedIn: false,
31
+ showRestartSubscriptionButton: false,
21
32
  showUserNavigation: true
22
33
  }
23
34
 
24
35
  const commonHeader = <Header {...headerFixture} />
25
36
  const subscribedUserHeader = <Header {...subscribedUserFixture} />
26
37
  const loggedInUserHeader = <Header {...loggedInUserFixture} />
38
+ const loggedInUserWithoutRestartHeader = <Header {...loggedInUserWithoutRestartFixture} />
27
39
  const anonymousUserHeader = <Header {...anonymousUserFixture} />
28
40
 
29
41
  describe('dotcom-ui-header', () => {
@@ -87,6 +99,18 @@ describe('dotcom-ui-header', () => {
87
99
  expect(container.querySelector('a[data-trackable="Subscribe"]')).not.toBeNull()
88
100
  expect(container.querySelector('a[data-trackable="Sign In"]')).toBeNull()
89
101
  })
102
+
103
+ it('renders restart subscription button when showRestartSubscriptionButton is true', () => {
104
+ const { container } = render(loggedInUserHeader)
105
+
106
+ expect(container.querySelector('a[data-trackable="Restart Subscription"]')).not.toBeNull()
107
+ })
108
+
109
+ it('does not render restart subscription button when showRestartSubscriptionButton is false', () => {
110
+ const { container } = render(loggedInUserWithoutRestartHeader)
111
+
112
+ expect(container.querySelector('a[data-trackable="Restart Subscription"]')).toBeNull()
113
+ })
90
114
  })
91
115
 
92
116
  describe('When the user is anonymous', () => {
@@ -109,10 +109,20 @@ const TopColumnCenterNoLink = () => (
109
109
  )
110
110
 
111
111
  const TopColumnRightLoggedIn = (props: THeaderProps) => {
112
- const signInAction = props.data['navbar-top-right']?.items?.[0]
113
- const subscribeAction = props.data['navbar-top-right']?.items?.[1]
112
+ const [
113
+ signInAction,
114
+ subscribeAction,
115
+ restartSubscriptionAction
116
+ ] = props.data['navbar-top-right']?.items ?? [];
114
117
  return (
115
118
  <div className="o-header__top-column o-header__top-column--right">
119
+ {props.showRestartSubscriptionButton && restartSubscriptionAction && (
120
+ <RestartSubscriptionButton
121
+ item={restartSubscriptionAction}
122
+ variant={props.variant}
123
+ className="o3-button o3-button--primary"
124
+ />
125
+ )}
116
126
  {!props.userIsSubscribed && subscribeAction && (
117
127
  <SubscribeButton
118
128
  item={subscribeAction}
@@ -197,6 +207,22 @@ const SubscribeButton = ({
197
207
  )
198
208
  }
199
209
 
210
+
211
+ const RestartSubscriptionButton = ({ item, className, variant }: { item: TNavMenuItem, className?: string, variant?: THeaderVariant }) => {
212
+ const setTabIndex = variant === 'sticky' ? { tabIndex: -1 } : null
213
+ return (
214
+ <a
215
+ className={`o-header__top-button ${className}`}
216
+ role="button"
217
+ href={item.url ?? undefined}
218
+ data-trackable={item.label}
219
+ {...setTabIndex}
220
+ >
221
+ {item.label}
222
+ </a>
223
+ )
224
+ }
225
+
200
226
  const TopColumnRightAnon = ({ items, variant }: { items: TNavMenuItem[]; variant?: THeaderVariant }) => {
201
227
  // If user is anonymous the second list item is styled as a button
202
228
  const [signInAction, subscribeAction] = items
@@ -12,6 +12,7 @@ export type THeaderOptions = {
12
12
  showLogoLink?: boolean
13
13
  showAskButton?: boolean
14
14
  showProNavigation?: boolean
15
+ showRestartSubscriptionButton?: boolean
15
16
  }
16
17
 
17
18
  export type THeaderProps = THeaderOptions & {