@financial-times/dotcom-ui-header 13.8.1-beta.0 → 13.9.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.
- package/README.md +14 -0
- package/browser.js +13 -13
- package/dist/node/components/search/partials.js +16 -14
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/src/__test__/components/__snapshots__/MainHeader.spec.tsx.snap +552 -488
- package/src/__test__/components/__snapshots__/StickyHeader.spec.tsx.snap +345 -305
- package/src/__test__/output/component.spec.tsx +32 -0
- package/src/components/search/partials.tsx +46 -42
- package/src/header.scss +32 -0
|
@@ -67,6 +67,38 @@ describe('dotcom-ui-header', () => {
|
|
|
67
67
|
expect(mobileHeader).not.toBeNull()
|
|
68
68
|
})
|
|
69
69
|
|
|
70
|
+
it('renders one search widget anchor in the primary search row', () => {
|
|
71
|
+
const { container } = render(commonHeader)
|
|
72
|
+
const primarySearch = container.querySelector('#o-header-search-primary')
|
|
73
|
+
const primarySearchMain = primarySearch?.querySelector('.o-header__search-main')
|
|
74
|
+
const primaryForm = primarySearch?.querySelector('.o-header__search-form')
|
|
75
|
+
const primaryAnchor = primarySearch?.querySelector('[data-o-header-search-widget-anchor="primary"]')
|
|
76
|
+
const primaryAnchors = container.querySelectorAll('[data-o-header-search-widget-anchor="primary"]')
|
|
77
|
+
const widgetAnchors = container.querySelectorAll('[data-o-header-search-widget-anchor]')
|
|
78
|
+
|
|
79
|
+
expect(primarySearchMain).not.toBeNull()
|
|
80
|
+
expect(primaryForm?.parentElement).toBe(primarySearchMain)
|
|
81
|
+
expect(primarySearchMain?.nextElementSibling).toBe(primaryAnchor)
|
|
82
|
+
expect(primaryAnchors).toHaveLength(1)
|
|
83
|
+
expect(widgetAnchors).toHaveLength(2)
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
it('renders one search widget anchor in sticky search', () => {
|
|
87
|
+
const { container } = render(commonHeader)
|
|
88
|
+
const searchMainNodes = container.querySelectorAll('.o-header__search-main')
|
|
89
|
+
const stickySearch = container.querySelector('#o-header-search-sticky')
|
|
90
|
+
const stickySearchMain = stickySearch?.querySelector('.o-header__search-main')
|
|
91
|
+
const stickyForm = stickySearch?.querySelector('.o-header__search-form')
|
|
92
|
+
const stickyAnchor = stickySearch?.querySelector('[data-o-header-search-widget-anchor="sticky"]')
|
|
93
|
+
const stickyAnchors = container.querySelectorAll('[data-o-header-search-widget-anchor="sticky"]')
|
|
94
|
+
|
|
95
|
+
expect(searchMainNodes).toHaveLength(2)
|
|
96
|
+
expect(stickySearchMain).not.toBeNull()
|
|
97
|
+
expect(stickyForm?.parentElement).toBe(stickySearchMain)
|
|
98
|
+
expect(stickySearchMain?.nextElementSibling).toBe(stickyAnchor)
|
|
99
|
+
expect(stickyAnchors).toHaveLength(1)
|
|
100
|
+
})
|
|
101
|
+
|
|
70
102
|
describe('When the user is subscribed', () => {
|
|
71
103
|
it('renders the expected logged in user header links', () => {
|
|
72
104
|
const { container } = render(subscribedUserHeader)
|
|
@@ -2,6 +2,7 @@ import React from 'react'
|
|
|
2
2
|
|
|
3
3
|
const Search = ({ instance }) => {
|
|
4
4
|
const inputId = `o-header-search-term-${instance}`
|
|
5
|
+
|
|
5
6
|
return (
|
|
6
7
|
<div
|
|
7
8
|
id={`o-header-search-${instance}`}
|
|
@@ -11,49 +12,52 @@ const Search = ({ instance }) => {
|
|
|
11
12
|
data-o-header-search
|
|
12
13
|
>
|
|
13
14
|
<div className="o-header__container">
|
|
14
|
-
<
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
<
|
|
23
|
-
<span className="o-forms-
|
|
24
|
-
|
|
15
|
+
<div className="o-header__search-main">
|
|
16
|
+
<form
|
|
17
|
+
className="o-header__search-form"
|
|
18
|
+
action="/search"
|
|
19
|
+
role="search"
|
|
20
|
+
aria-label="Site search"
|
|
21
|
+
data-n-topic-search
|
|
22
|
+
>
|
|
23
|
+
<label htmlFor={inputId} className="o-header__search-term o-forms-field o-forms-field--optional">
|
|
24
|
+
<span className="o-forms-title o-header__visually-hidden">
|
|
25
|
+
<span className="o-forms-title__main">
|
|
26
|
+
Search the <abbr title="Financial Times">FT</abbr>
|
|
27
|
+
</span>
|
|
28
|
+
</span>
|
|
29
|
+
<span className="o-forms-input o-forms-input--text o-forms-input--suffix">
|
|
30
|
+
<input
|
|
31
|
+
id={inputId}
|
|
32
|
+
name="q"
|
|
33
|
+
type="search"
|
|
34
|
+
autoComplete="off"
|
|
35
|
+
autoCorrect="off"
|
|
36
|
+
autoCapitalize="off"
|
|
37
|
+
spellCheck={false}
|
|
38
|
+
placeholder="Search for stories, topics or securities"
|
|
39
|
+
role="combobox"
|
|
40
|
+
aria-controls={`suggestions-${inputId}`}
|
|
41
|
+
/>
|
|
42
|
+
<button className="o-header__search-submit" type="submit">
|
|
43
|
+
<span aria-hidden="true" className="o-header__search-icon"></span>
|
|
44
|
+
<span>Search</span>
|
|
45
|
+
</button>
|
|
46
|
+
<button
|
|
47
|
+
className="o-header__search-close o--if-js"
|
|
48
|
+
type="button"
|
|
49
|
+
aria-controls={`o-header-search-${instance}`}
|
|
50
|
+
title="Close search bar"
|
|
51
|
+
data-trackable="close"
|
|
52
|
+
>
|
|
53
|
+
<span className="o-header__visually-hidden">Close search bar</span>
|
|
54
|
+
<span>Close</span>
|
|
55
|
+
</button>
|
|
25
56
|
</span>
|
|
26
|
-
</
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
name="q"
|
|
31
|
-
type="search"
|
|
32
|
-
autoComplete="off"
|
|
33
|
-
autoCorrect="off"
|
|
34
|
-
autoCapitalize="off"
|
|
35
|
-
spellCheck={false}
|
|
36
|
-
placeholder="Search for stories, topics or securities"
|
|
37
|
-
role="combobox"
|
|
38
|
-
aria-controls={`suggestions-${inputId}`}
|
|
39
|
-
/>
|
|
40
|
-
<button className="o-header__search-submit" type="submit">
|
|
41
|
-
<span aria-hidden="true" className="o-header__search-icon"></span>
|
|
42
|
-
<span>Search</span>
|
|
43
|
-
</button>
|
|
44
|
-
<button
|
|
45
|
-
className="o-header__search-close o--if-js"
|
|
46
|
-
type="button"
|
|
47
|
-
aria-controls={`o-header-search-${instance}`}
|
|
48
|
-
title="Close search bar"
|
|
49
|
-
data-trackable="close"
|
|
50
|
-
>
|
|
51
|
-
<span className="o-header__visually-hidden">Close search bar</span>
|
|
52
|
-
<span>Close</span>
|
|
53
|
-
</button>
|
|
54
|
-
</span>
|
|
55
|
-
</label>
|
|
56
|
-
</form>
|
|
57
|
+
</label>
|
|
58
|
+
</form>
|
|
59
|
+
</div>
|
|
60
|
+
<div className="o-header__search-widget-anchor" data-o-header-search-widget-anchor={instance} />
|
|
57
61
|
</div>
|
|
58
62
|
</div>
|
|
59
63
|
)
|
package/src/header.scss
CHANGED
|
@@ -16,6 +16,38 @@
|
|
|
16
16
|
display: none;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
+
.o-header__search-widget-anchor[data-o-header-search-widget-anchor] {
|
|
20
|
+
display: none;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Grid layout on large sizes to create right hand rail for widget anchor
|
|
24
|
+
@include oGridRespondTo('L') {
|
|
25
|
+
.o-header__search--primary .o-header__container,
|
|
26
|
+
.o-header__search--sticky .o-header__container {
|
|
27
|
+
max-width: none;
|
|
28
|
+
display: grid;
|
|
29
|
+
grid-template-columns: minmax(0, 1fr) minmax(0, 840px) minmax(0, 1fr);
|
|
30
|
+
column-gap: var(--o3-spacing-3xs);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.o-header__search--primary .o-header__search-main,
|
|
34
|
+
.o-header__search--sticky .o-header__search-main {
|
|
35
|
+
grid-column: 2;
|
|
36
|
+
grid-row: 1;
|
|
37
|
+
min-width: 0;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.o-header__search--primary .o-header__search-widget-anchor[data-o-header-search-widget-anchor='primary'],
|
|
41
|
+
.o-header__search--sticky .o-header__search-widget-anchor[data-o-header-search-widget-anchor='sticky'] {
|
|
42
|
+
grid-column: 3;
|
|
43
|
+
display: block;
|
|
44
|
+
width: 100%;
|
|
45
|
+
min-width: 0;
|
|
46
|
+
overflow-x: hidden;
|
|
47
|
+
overflow-y: visible;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
19
51
|
// Import the dropdown navigation styles
|
|
20
52
|
@import 'components/dropdown-navigation/dropdownNavigation.scss';
|
|
21
53
|
|