@internetarchive/ia-topnav 1.4.1 → 2.0.1-alpha-webdev8396.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/.prettierignore +1 -1
- package/LICENSE +661 -661
- package/README.md +147 -147
- package/demo/index.html +28 -28
- package/dist/src/data/menus.js +0 -2
- package/dist/src/data/menus.js.map +1 -1
- package/dist/src/dropdown-menu.d.ts +3 -4
- package/dist/src/dropdown-menu.js +6 -13
- package/dist/src/dropdown-menu.js.map +1 -1
- package/dist/src/ia-topnav.d.ts +10 -10
- package/dist/src/ia-topnav.js +39 -67
- package/dist/src/ia-topnav.js.map +1 -1
- package/dist/src/login-button.d.ts +3 -0
- package/dist/src/login-button.js +11 -1
- package/dist/src/login-button.js.map +1 -1
- package/dist/src/models.d.ts +0 -4
- package/dist/src/models.js.map +1 -1
- package/dist/src/primary-nav.d.ts +9 -4
- package/dist/src/primary-nav.js +34 -36
- package/dist/src/primary-nav.js.map +1 -1
- package/dist/src/signed-out-dropdown.d.ts +1 -1
- package/dist/src/signed-out-dropdown.js +1 -2
- package/dist/src/signed-out-dropdown.js.map +1 -1
- package/dist/src/styles/dropdown-menu.js +1 -0
- package/dist/src/styles/dropdown-menu.js.map +1 -1
- package/dist/src/styles/ia-topnav.js +0 -5
- package/dist/src/styles/ia-topnav.js.map +1 -1
- package/dist/src/styles/primary-nav.js +50 -5
- package/dist/src/styles/primary-nav.js.map +1 -1
- package/dist/src/user-menu.d.ts +1 -2
- package/dist/src/user-menu.js +1 -2
- package/dist/src/user-menu.js.map +1 -1
- package/dist/test/ia-topnav.test.js +18 -60
- package/dist/test/ia-topnav.test.js.map +1 -1
- package/dist/test/primary-nav.test.js +31 -2
- package/dist/test/primary-nav.test.js.map +1 -1
- package/eslint.config.mjs +53 -53
- package/package.json +72 -72
- package/prettier.config.js +9 -9
- package/src/data/menus.ts +0 -2
- package/src/dropdown-menu.ts +6 -12
- package/src/ia-topnav.ts +44 -78
- package/src/login-button.ts +12 -1
- package/src/models.ts +0 -5
- package/src/primary-nav.ts +38 -34
- package/src/signed-out-dropdown.ts +1 -2
- package/src/styles/dropdown-menu.ts +1 -0
- package/src/styles/ia-topnav.ts +0 -5
- package/src/styles/primary-nav.ts +50 -5
- package/src/user-menu.ts +3 -4
- package/ssl/server.key +28 -28
- package/test/ia-topnav.test.ts +20 -81
- package/test/primary-nav.test.ts +43 -2
- package/tsconfig.json +31 -31
- package/web-dev-server.config.mjs +32 -32
- package/web-test-runner.config.mjs +41 -41
- package/dist/src/lib/location-handler.d.ts +0 -1
- package/dist/src/lib/location-handler.js +0 -5
- package/dist/src/lib/location-handler.js.map +0 -1
- package/dist/src/nav-search.d.ts +0 -19
- package/dist/src/nav-search.js +0 -127
- package/dist/src/nav-search.js.map +0 -1
- package/dist/src/search-menu.d.ts +0 -20
- package/dist/src/search-menu.js +0 -162
- package/dist/src/search-menu.js.map +0 -1
- package/dist/src/styles/nav-search.d.ts +0 -2
- package/dist/src/styles/nav-search.js +0 -136
- package/dist/src/styles/nav-search.js.map +0 -1
- package/dist/src/styles/search-menu.d.ts +0 -2
- package/dist/src/styles/search-menu.js +0 -118
- package/dist/src/styles/search-menu.js.map +0 -1
- package/dist/src/styles/signed-out-dropdown.d.ts +0 -2
- package/dist/src/styles/signed-out-dropdown.js +0 -31
- package/dist/src/styles/signed-out-dropdown.js.map +0 -1
- package/dist/src/styles/user-menu.d.ts +0 -2
- package/dist/src/styles/user-menu.js +0 -31
- package/dist/src/styles/user-menu.js.map +0 -1
- package/dist/test/nav-search.test.d.ts +0 -1
- package/dist/test/nav-search.test.js +0 -47
- package/dist/test/nav-search.test.js.map +0 -1
- package/dist/test/search-menu.test.d.ts +0 -1
- package/dist/test/search-menu.test.js +0 -42
- package/dist/test/search-menu.test.js.map +0 -1
- package/src/lib/location-handler.ts +0 -5
- package/src/nav-search.ts +0 -117
- package/src/search-menu.ts +0 -156
- package/src/styles/nav-search.ts +0 -136
- package/src/styles/search-menu.ts +0 -118
- package/src/styles/signed-out-dropdown.ts +0 -31
- package/src/styles/user-menu.ts +0 -31
- package/test/nav-search.test.ts +0 -70
- package/test/search-menu.test.ts +0 -58
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
import { css } from 'lit';
|
|
2
|
-
export default css `
|
|
3
|
-
.menu-wrapper {
|
|
4
|
-
position: relative;
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
button:focus,
|
|
8
|
-
input:focus {
|
|
9
|
-
outline-color: var(--linkColor);
|
|
10
|
-
outline-width: 0.16rem;
|
|
11
|
-
outline-style: auto;
|
|
12
|
-
outline-offset: 2px !important;
|
|
13
|
-
}
|
|
14
|
-
.search-menu-inner {
|
|
15
|
-
position: absolute;
|
|
16
|
-
right: 0;
|
|
17
|
-
left: 0;
|
|
18
|
-
z-index: 4;
|
|
19
|
-
padding: 0 4.5rem;
|
|
20
|
-
font-size: 1.6rem;
|
|
21
|
-
background-color: var(--searchMenuBg);
|
|
22
|
-
}
|
|
23
|
-
.tx-slide {
|
|
24
|
-
overflow: hidden;
|
|
25
|
-
transition-property: top;
|
|
26
|
-
transition-duration: 0.2s;
|
|
27
|
-
transition-timing-function: ease;
|
|
28
|
-
}
|
|
29
|
-
.initial,
|
|
30
|
-
.closed {
|
|
31
|
-
top: var(--topOffset, -1500px);
|
|
32
|
-
}
|
|
33
|
-
.closed {
|
|
34
|
-
transition-duration: 0.2s;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
label,
|
|
38
|
-
a {
|
|
39
|
-
padding: 1rem;
|
|
40
|
-
display: block;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
.advanced-search {
|
|
44
|
-
text-decoration: underline;
|
|
45
|
-
color: inherit;
|
|
46
|
-
line-height: normal;
|
|
47
|
-
padding: 0.5rem;
|
|
48
|
-
margin-top: 5px;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
.advanced-search:hover {
|
|
52
|
-
text-decoration: none;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
@media (min-width: 890px) {
|
|
56
|
-
.search-menu-inner {
|
|
57
|
-
overflow: visible;
|
|
58
|
-
right: 2rem;
|
|
59
|
-
left: auto;
|
|
60
|
-
z-index: 5;
|
|
61
|
-
padding: 1rem 2rem;
|
|
62
|
-
transition: opacity 0.2s ease-in-out;
|
|
63
|
-
font-size: 1.4rem;
|
|
64
|
-
color: var(--inverseTextColor);
|
|
65
|
-
border-radius: 2px;
|
|
66
|
-
background: var(--primaryTextColor);
|
|
67
|
-
box-shadow: 0 1px 2px 1px rgba(0, 0, 0, 0.15);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
.search-menu-inner:after {
|
|
71
|
-
position: absolute;
|
|
72
|
-
right: 7px;
|
|
73
|
-
top: -7px;
|
|
74
|
-
width: 12px;
|
|
75
|
-
height: 7px;
|
|
76
|
-
box-sizing: border-box;
|
|
77
|
-
color: #fff;
|
|
78
|
-
content: '';
|
|
79
|
-
border-bottom: 7px solid currentColor;
|
|
80
|
-
border-left: 6px solid transparent;
|
|
81
|
-
border-right: 6px solid transparent;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
.advanced-search {
|
|
85
|
-
text-decoration: none;
|
|
86
|
-
color: var(--linkColor);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
.advanced-search:hover {
|
|
90
|
-
text-decoration: underline;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
.initial,
|
|
94
|
-
.closed {
|
|
95
|
-
opacity: 0;
|
|
96
|
-
transition-duration: 0.2s;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
.open {
|
|
100
|
-
opacity: 1;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
label {
|
|
104
|
-
padding: 0;
|
|
105
|
-
font-weight: normal;
|
|
106
|
-
margin: 0;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
label + label {
|
|
110
|
-
padding-top: 7px;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
a {
|
|
114
|
-
padding: 1rem 0 0 0;
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
`;
|
|
118
|
-
//# sourceMappingURL=search-menu.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"search-menu.js","sourceRoot":"","sources":["../../../src/styles/search-menu.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAE1B,eAAe,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmHjB,CAAC","sourcesContent":["import { css } from 'lit';\n\nexport default css`\n .menu-wrapper {\n position: relative;\n }\n\n button:focus,\n input:focus {\n outline-color: var(--linkColor);\n outline-width: 0.16rem;\n outline-style: auto;\n outline-offset: 2px !important;\n }\n .search-menu-inner {\n position: absolute;\n right: 0;\n left: 0;\n z-index: 4;\n padding: 0 4.5rem;\n font-size: 1.6rem;\n background-color: var(--searchMenuBg);\n }\n .tx-slide {\n overflow: hidden;\n transition-property: top;\n transition-duration: 0.2s;\n transition-timing-function: ease;\n }\n .initial,\n .closed {\n top: var(--topOffset, -1500px);\n }\n .closed {\n transition-duration: 0.2s;\n }\n\n label,\n a {\n padding: 1rem;\n display: block;\n }\n\n .advanced-search {\n text-decoration: underline;\n color: inherit;\n line-height: normal;\n padding: 0.5rem;\n margin-top: 5px;\n }\n\n .advanced-search:hover {\n text-decoration: none;\n }\n\n @media (min-width: 890px) {\n .search-menu-inner {\n overflow: visible;\n right: 2rem;\n left: auto;\n z-index: 5;\n padding: 1rem 2rem;\n transition: opacity 0.2s ease-in-out;\n font-size: 1.4rem;\n color: var(--inverseTextColor);\n border-radius: 2px;\n background: var(--primaryTextColor);\n box-shadow: 0 1px 2px 1px rgba(0, 0, 0, 0.15);\n }\n\n .search-menu-inner:after {\n position: absolute;\n right: 7px;\n top: -7px;\n width: 12px;\n height: 7px;\n box-sizing: border-box;\n color: #fff;\n content: '';\n border-bottom: 7px solid currentColor;\n border-left: 6px solid transparent;\n border-right: 6px solid transparent;\n }\n\n .advanced-search {\n text-decoration: none;\n color: var(--linkColor);\n }\n\n .advanced-search:hover {\n text-decoration: underline;\n }\n\n .initial,\n .closed {\n opacity: 0;\n transition-duration: 0.2s;\n }\n\n .open {\n opacity: 1;\n }\n\n label {\n padding: 0;\n font-weight: normal;\n margin: 0;\n }\n\n label + label {\n padding-top: 7px;\n }\n\n a {\n padding: 1rem 0 0 0;\n }\n }\n`;\n"]}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { css } from 'lit';
|
|
2
|
-
export default css `
|
|
3
|
-
@media (min-width: 890px) {
|
|
4
|
-
.initial,
|
|
5
|
-
.closed,
|
|
6
|
-
.open {
|
|
7
|
-
right: 33.5rem;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
.search-hidden.initial,
|
|
11
|
-
.search-hidden.closed,
|
|
12
|
-
.search-hidden.open {
|
|
13
|
-
right: 18.5rem;
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
@media (min-width: 990px) {
|
|
18
|
-
.initial,
|
|
19
|
-
.closed,
|
|
20
|
-
.open {
|
|
21
|
-
right: 40rem;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
.search-hidden.initial,
|
|
25
|
-
.search-hidden.closed,
|
|
26
|
-
.search-hidden.open {
|
|
27
|
-
right: 26rem;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
`;
|
|
31
|
-
//# sourceMappingURL=signed-out-dropdown.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"signed-out-dropdown.js","sourceRoot":"","sources":["../../../src/styles/signed-out-dropdown.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAE1B,eAAe,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4BjB,CAAC","sourcesContent":["import { css } from 'lit';\n\nexport default css`\n @media (min-width: 890px) {\n .initial,\n .closed,\n .open {\n right: 33.5rem;\n }\n\n .search-hidden.initial,\n .search-hidden.closed,\n .search-hidden.open {\n right: 18.5rem;\n }\n }\n\n @media (min-width: 990px) {\n .initial,\n .closed,\n .open {\n right: 40rem;\n }\n\n .search-hidden.initial,\n .search-hidden.closed,\n .search-hidden.open {\n right: 26rem;\n }\n }\n`;\n"]}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { css } from 'lit';
|
|
2
|
-
export default css `
|
|
3
|
-
@media (min-width: 890px) {
|
|
4
|
-
.initial,
|
|
5
|
-
.closed,
|
|
6
|
-
.open {
|
|
7
|
-
right: 22.4rem;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
.search-hidden.initial,
|
|
11
|
-
.search-hidden.closed,
|
|
12
|
-
.search-hidden.open {
|
|
13
|
-
right: 5.8rem;
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
@media (min-width: 990px) {
|
|
18
|
-
.initial,
|
|
19
|
-
.closed,
|
|
20
|
-
.open {
|
|
21
|
-
right: 27.2rem;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
.search-hidden.initial,
|
|
25
|
-
.search-hidden.closed,
|
|
26
|
-
.search-hidden.open {
|
|
27
|
-
right: 12rem;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
`;
|
|
31
|
-
//# sourceMappingURL=user-menu.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"user-menu.js","sourceRoot":"","sources":["../../../src/styles/user-menu.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAE1B,eAAe,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4BjB,CAAC","sourcesContent":["import { css } from 'lit';\n\nexport default css`\n @media (min-width: 890px) {\n .initial,\n .closed,\n .open {\n right: 22.4rem;\n }\n\n .search-hidden.initial,\n .search-hidden.closed,\n .search-hidden.open {\n right: 5.8rem;\n }\n }\n\n @media (min-width: 990px) {\n .initial,\n .closed,\n .open {\n right: 27.2rem;\n }\n\n .search-hidden.initial,\n .search-hidden.closed,\n .search-hidden.open {\n right: 12rem;\n }\n }\n`;\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import '../src/nav-search';
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { html, fixture, expect } from '@open-wc/testing';
|
|
2
|
-
import sinon from 'sinon';
|
|
3
|
-
import '../src/nav-search';
|
|
4
|
-
const component = html `<nav-search></nav-search>`;
|
|
5
|
-
describe('<nav-search>', () => {
|
|
6
|
-
it('defaults to closed', async () => {
|
|
7
|
-
const el = await fixture(component);
|
|
8
|
-
expect(el.open).to.be.false;
|
|
9
|
-
});
|
|
10
|
-
it('does not allow search form to submit if query empty', async () => {
|
|
11
|
-
const el = await fixture(component);
|
|
12
|
-
// const result = el.search({
|
|
13
|
-
// preventDefault: () => {},
|
|
14
|
-
// });
|
|
15
|
-
// expect(result).to.be.false;
|
|
16
|
-
});
|
|
17
|
-
it('redirects to the TV details page when search inside is TV', async () => {
|
|
18
|
-
const query = 'bananas';
|
|
19
|
-
const submitEvent = {
|
|
20
|
-
type: 'submit',
|
|
21
|
-
preventDefault: () => { },
|
|
22
|
-
};
|
|
23
|
-
const locationHandler = sinon.fake();
|
|
24
|
-
const el = await fixture(html `<nav-search .locationHandler=${locationHandler}></nav-search>`);
|
|
25
|
-
el.searchIn = 'TV';
|
|
26
|
-
await el.updateComplete;
|
|
27
|
-
// el.shadowRoot.querySelector('[name=query]').value = query;
|
|
28
|
-
// el.search(submitEvent);
|
|
29
|
-
// expect(locationHandler.callCount).to.equal(1);
|
|
30
|
-
// expect(locationHandler.firstArg).to.contain(`/details/tv?q=${query}`);
|
|
31
|
-
});
|
|
32
|
-
it('prefills the search query when present in config', async () => {
|
|
33
|
-
var _a;
|
|
34
|
-
const el = await fixture(html `<nav-search searchQuery="bananas"></nav-search>`);
|
|
35
|
-
const queryInput = (_a = el.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('[name="query"]');
|
|
36
|
-
expect(queryInput.value).to.equal('bananas');
|
|
37
|
-
});
|
|
38
|
-
it('conditionally renders `sin` input based on `searchIn` truthiness', async () => {
|
|
39
|
-
var _a, _b;
|
|
40
|
-
const el = await fixture(component);
|
|
41
|
-
expect((_a = el.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('[name="sin"]')).to.be.null;
|
|
42
|
-
el.searchIn = 'TV';
|
|
43
|
-
await el.updateComplete;
|
|
44
|
-
expect((_b = el.shadowRoot) === null || _b === void 0 ? void 0 : _b.querySelector('[name="sin"]')).not.to.be.null;
|
|
45
|
-
});
|
|
46
|
-
});
|
|
47
|
-
//# sourceMappingURL=nav-search.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"nav-search.test.js","sourceRoot":"","sources":["../../test/nav-search.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,mBAAmB,CAAC;AAG3B,MAAM,SAAS,GAAG,IAAI,CAAA,2BAA2B,CAAC;AAElD,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;IAC5B,EAAE,CAAC,oBAAoB,EAAE,KAAK,IAAI,EAAE;QAClC,MAAM,EAAE,GAAG,MAAM,OAAO,CAAY,SAAS,CAAC,CAAC;QAE/C,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC;IAC9B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qDAAqD,EAAE,KAAK,IAAI,EAAE;QACnE,MAAM,EAAE,GAAG,MAAM,OAAO,CAAY,SAAS,CAAC,CAAC;QAE/C,6BAA6B;QAC7B,8BAA8B;QAC9B,MAAM;QAEN,8BAA8B;IAChC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2DAA2D,EAAE,KAAK,IAAI,EAAE;QACzE,MAAM,KAAK,GAAG,SAAS,CAAC;QACxB,MAAM,WAAW,GAAG;YAClB,IAAI,EAAE,QAAQ;YACd,cAAc,EAAE,GAAG,EAAE,GAAE,CAAC;SACzB,CAAC;QACF,MAAM,eAAe,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;QACrC,MAAM,EAAE,GAAG,MAAM,OAAO,CACtB,IAAI,CAAA,gCAAgC,eAAe,gBAAgB,CACpE,CAAC;QAEF,EAAE,CAAC,QAAQ,GAAG,IAAI,CAAC;QAEnB,MAAM,EAAE,CAAC,cAAc,CAAC;QAExB,6DAA6D;QAC7D,0BAA0B;QAE1B,iDAAiD;QACjD,yEAAyE;IAC3E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kDAAkD,EAAE,KAAK,IAAI,EAAE;;QAChE,MAAM,EAAE,GAAG,MAAM,OAAO,CACtB,IAAI,CAAA,iDAAiD,CACtD,CAAC;QAEF,MAAM,UAAU,GAAG,MAAA,EAAE,CAAC,UAAU,0CAAE,aAAa,CAC7C,gBAAgB,CACG,CAAC;QAEtB,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kEAAkE,EAAE,KAAK,IAAI,EAAE;;QAChF,MAAM,EAAE,GAAG,MAAM,OAAO,CAAY,SAAS,CAAC,CAAC;QAE/C,MAAM,CAAC,MAAA,EAAE,CAAC,UAAU,0CAAE,aAAa,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC;QAEhE,EAAE,CAAC,QAAQ,GAAG,IAAI,CAAC;QACnB,MAAM,EAAE,CAAC,cAAc,CAAC;QAExB,MAAM,CAAC,MAAA,EAAE,CAAC,UAAU,0CAAE,aAAa,CAAC,cAAc,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC;IACtE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { html, fixture, expect } from '@open-wc/testing';\nimport sinon from 'sinon';\n\nimport '../src/nav-search';\nimport { NavSearch } from '../src/nav-search';\n\nconst component = html`<nav-search></nav-search>`;\n\ndescribe('<nav-search>', () => {\n it('defaults to closed', async () => {\n const el = await fixture<NavSearch>(component);\n\n expect(el.open).to.be.false;\n });\n\n it('does not allow search form to submit if query empty', async () => {\n const el = await fixture<NavSearch>(component);\n\n // const result = el.search({\n // preventDefault: () => {},\n // });\n\n // expect(result).to.be.false;\n });\n\n it('redirects to the TV details page when search inside is TV', async () => {\n const query = 'bananas';\n const submitEvent = {\n type: 'submit',\n preventDefault: () => {},\n };\n const locationHandler = sinon.fake();\n const el = await fixture<NavSearch>(\n html`<nav-search .locationHandler=${locationHandler}></nav-search>`,\n );\n\n el.searchIn = 'TV';\n\n await el.updateComplete;\n\n // el.shadowRoot.querySelector('[name=query]').value = query;\n // el.search(submitEvent);\n\n // expect(locationHandler.callCount).to.equal(1);\n // expect(locationHandler.firstArg).to.contain(`/details/tv?q=${query}`);\n });\n\n it('prefills the search query when present in config', async () => {\n const el = await fixture<NavSearch>(\n html`<nav-search searchQuery=\"bananas\"></nav-search>`,\n );\n\n const queryInput = el.shadowRoot?.querySelector(\n '[name=\"query\"]',\n ) as HTMLInputElement;\n\n expect(queryInput.value).to.equal('bananas');\n });\n\n it('conditionally renders `sin` input based on `searchIn` truthiness', async () => {\n const el = await fixture<NavSearch>(component);\n\n expect(el.shadowRoot?.querySelector('[name=\"sin\"]')).to.be.null;\n\n el.searchIn = 'TV';\n await el.updateComplete;\n\n expect(el.shadowRoot?.querySelector('[name=\"sin\"]')).not.to.be.null;\n });\n});\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import '../src/search-menu';
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import { html, fixture, expect } from '@open-wc/testing';
|
|
2
|
-
import '../src/search-menu';
|
|
3
|
-
const component = html `<search-menu></search-menu>`;
|
|
4
|
-
describe('<search-menu>', () => {
|
|
5
|
-
it('sets default properties', async () => {
|
|
6
|
-
const el = await fixture(component);
|
|
7
|
-
expect(el.searchMenuOpen).to.be.false;
|
|
8
|
-
expect(el.searchMenuAnimate).to.be.false;
|
|
9
|
-
expect(el.selectedSearchType).to.equal('');
|
|
10
|
-
});
|
|
11
|
-
it('sets selected search type', async () => {
|
|
12
|
-
const el = await fixture(component);
|
|
13
|
-
const value = 'text';
|
|
14
|
-
const inputEvent = new InputEvent('input');
|
|
15
|
-
Object.defineProperty(inputEvent, 'target', {
|
|
16
|
-
value: {
|
|
17
|
-
value,
|
|
18
|
-
},
|
|
19
|
-
writable: false,
|
|
20
|
-
});
|
|
21
|
-
el.selectSearchType(inputEvent);
|
|
22
|
-
expect(el.selectedSearchType).to.equal(value);
|
|
23
|
-
});
|
|
24
|
-
it('renders with closed class if done animating', async () => {
|
|
25
|
-
var _a, _b;
|
|
26
|
-
const el = await fixture(component);
|
|
27
|
-
el.searchMenuAnimate = true;
|
|
28
|
-
await el.updateComplete;
|
|
29
|
-
expect((_b = (_a = el.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('.search-menu-inner')) === null || _b === void 0 ? void 0 : _b.classList.contains('closed')).to.be.true;
|
|
30
|
-
});
|
|
31
|
-
it('omits rendering of an option when hiddenSearchOptions has a value', async () => {
|
|
32
|
-
const el = await fixture(component);
|
|
33
|
-
const hiddenSearchOptions = ['WEB', 'RADIO'];
|
|
34
|
-
el.config = { hiddenSearchOptions };
|
|
35
|
-
await el.updateComplete;
|
|
36
|
-
hiddenSearchOptions.forEach((value) => {
|
|
37
|
-
var _a;
|
|
38
|
-
expect((_a = el.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector(`[value=${value}]`)).to.equal(null);
|
|
39
|
-
});
|
|
40
|
-
});
|
|
41
|
-
});
|
|
42
|
-
//# sourceMappingURL=search-menu.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"search-menu.test.js","sourceRoot":"","sources":["../../test/search-menu.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAEzD,OAAO,oBAAoB,CAAC;AAG5B,MAAM,SAAS,GAAG,IAAI,CAAA,6BAA6B,CAAC;AAEpD,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;IAC7B,EAAE,CAAC,yBAAyB,EAAE,KAAK,IAAI,EAAE;QACvC,MAAM,EAAE,GAAG,MAAM,OAAO,CAAa,SAAS,CAAC,CAAC;QAEhD,MAAM,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC;QACtC,MAAM,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC;QACzC,MAAM,CAAC,EAAE,CAAC,kBAAkB,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2BAA2B,EAAE,KAAK,IAAI,EAAE;QACzC,MAAM,EAAE,GAAG,MAAM,OAAO,CAAa,SAAS,CAAC,CAAC;QAChD,MAAM,KAAK,GAAG,MAAM,CAAC;QAErB,MAAM,UAAU,GAAG,IAAI,UAAU,CAAC,OAAO,CAAC,CAAC;QAC3C,MAAM,CAAC,cAAc,CAAC,UAAU,EAAE,QAAQ,EAAE;YAC1C,KAAK,EAAE;gBACL,KAAK;aACN;YACD,QAAQ,EAAE,KAAK;SAChB,CAAC,CAAC;QAEH,EAAE,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC;QAEhC,MAAM,CAAC,EAAE,CAAC,kBAAkB,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE,KAAK,IAAI,EAAE;;QAC3D,MAAM,EAAE,GAAG,MAAM,OAAO,CAAa,SAAS,CAAC,CAAC;QAEhD,EAAE,CAAC,iBAAiB,GAAG,IAAI,CAAC;QAC5B,MAAM,EAAE,CAAC,cAAc,CAAC;QAExB,MAAM,CACJ,MAAA,MAAA,EAAE,CAAC,UAAU,0CACT,aAAa,CAAC,oBAAoB,CAAC,0CACnC,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,CACjC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC;IACf,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mEAAmE,EAAE,KAAK,IAAI,EAAE;QACjF,MAAM,EAAE,GAAG,MAAM,OAAO,CAAa,SAAS,CAAC,CAAC;QAChD,MAAM,mBAAmB,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAE7C,EAAE,CAAC,MAAM,GAAG,EAAE,mBAAmB,EAAE,CAAC;QACpC,MAAM,EAAE,CAAC,cAAc,CAAC;QAExB,mBAAmB,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;;YACpC,MAAM,CAAC,MAAA,EAAE,CAAC,UAAU,0CAAE,aAAa,CAAC,UAAU,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC1E,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { html, fixture, expect } from '@open-wc/testing';\n\nimport '../src/search-menu';\nimport { SearchMenu } from '../src/search-menu';\n\nconst component = html`<search-menu></search-menu>`;\n\ndescribe('<search-menu>', () => {\n it('sets default properties', async () => {\n const el = await fixture<SearchMenu>(component);\n\n expect(el.searchMenuOpen).to.be.false;\n expect(el.searchMenuAnimate).to.be.false;\n expect(el.selectedSearchType).to.equal('');\n });\n\n it('sets selected search type', async () => {\n const el = await fixture<SearchMenu>(component);\n const value = 'text';\n\n const inputEvent = new InputEvent('input');\n Object.defineProperty(inputEvent, 'target', {\n value: {\n value,\n },\n writable: false,\n });\n\n el.selectSearchType(inputEvent);\n\n expect(el.selectedSearchType).to.equal(value);\n });\n\n it('renders with closed class if done animating', async () => {\n const el = await fixture<SearchMenu>(component);\n\n el.searchMenuAnimate = true;\n await el.updateComplete;\n\n expect(\n el.shadowRoot\n ?.querySelector('.search-menu-inner')\n ?.classList.contains('closed'),\n ).to.be.true;\n });\n\n it('omits rendering of an option when hiddenSearchOptions has a value', async () => {\n const el = await fixture<SearchMenu>(component);\n const hiddenSearchOptions = ['WEB', 'RADIO'];\n\n el.config = { hiddenSearchOptions };\n await el.updateComplete;\n\n hiddenSearchOptions.forEach((value) => {\n expect(el.shadowRoot?.querySelector(`[value=${value}]`)).to.equal(null);\n });\n });\n});\n"]}
|
package/src/nav-search.ts
DELETED
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
import { nothing, html } from 'lit';
|
|
2
|
-
|
|
3
|
-
import TrackedElement from './tracked-element';
|
|
4
|
-
import navSearchCSS from './styles/nav-search';
|
|
5
|
-
import icons from './assets/img/icons';
|
|
6
|
-
import formatUrl from './lib/format-url';
|
|
7
|
-
import { customElement, property, query } from 'lit/decorators.js';
|
|
8
|
-
import { defaultTopNavConfig } from './data/menus';
|
|
9
|
-
import { IATopNavConfig } from './models';
|
|
10
|
-
import { iaSronlyStyles } from '@internetarchive/ia-styles';
|
|
11
|
-
|
|
12
|
-
@customElement('nav-search')
|
|
13
|
-
export class NavSearch extends TrackedElement {
|
|
14
|
-
@property({ type: String }) baseHost = '';
|
|
15
|
-
@property({ type: Object }) config: IATopNavConfig = defaultTopNavConfig;
|
|
16
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
17
|
-
@property({ type: Object }) locationHandler = (url: string) => {};
|
|
18
|
-
@property({ type: Boolean }) open = false;
|
|
19
|
-
@property({ type: String }) openMenu = '';
|
|
20
|
-
@property({ type: String }) searchIn = '';
|
|
21
|
-
@property({ type: String }) searchQuery = '';
|
|
22
|
-
|
|
23
|
-
@query('[name=query]') private queryInput?: HTMLInputElement;
|
|
24
|
-
|
|
25
|
-
static get styles() {
|
|
26
|
-
return [navSearchCSS, iaSronlyStyles];
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
search(e: CustomEvent) {
|
|
30
|
-
const query = this.queryInput?.value;
|
|
31
|
-
|
|
32
|
-
if (!query) {
|
|
33
|
-
e.preventDefault();
|
|
34
|
-
return false;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
// TV search points to a detail page with a q param instead
|
|
38
|
-
if (this.searchIn === 'TV') {
|
|
39
|
-
this.locationHandler(
|
|
40
|
-
formatUrl(`/details/tv?q=${query}` as string & Location, this.baseHost),
|
|
41
|
-
);
|
|
42
|
-
e.preventDefault();
|
|
43
|
-
return false;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
this.trackSubmit(e);
|
|
47
|
-
return true;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
toggleSearchMenu() {
|
|
51
|
-
if (this.openMenu === 'search') {
|
|
52
|
-
return;
|
|
53
|
-
}
|
|
54
|
-
this.dispatchEvent(
|
|
55
|
-
new CustomEvent('menuToggled', {
|
|
56
|
-
detail: {
|
|
57
|
-
menuName: 'search',
|
|
58
|
-
},
|
|
59
|
-
composed: true,
|
|
60
|
-
bubbles: true,
|
|
61
|
-
}),
|
|
62
|
-
);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
get searchInsideInput() {
|
|
66
|
-
return this.searchIn
|
|
67
|
-
? html`<input type="hidden" name="sin" value="${this.searchIn}" />`
|
|
68
|
-
: nothing;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
get searchEndpoint() {
|
|
72
|
-
return '/search';
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
render() {
|
|
76
|
-
const searchMenuClass = this.open ? 'flex' : 'search-inactive';
|
|
77
|
-
|
|
78
|
-
return html`
|
|
79
|
-
<div class="search-activated fade-in ${searchMenuClass}">
|
|
80
|
-
<form
|
|
81
|
-
id="nav-search"
|
|
82
|
-
class="highlight"
|
|
83
|
-
.action=${formatUrl(
|
|
84
|
-
this.searchEndpoint as string & Location,
|
|
85
|
-
this.baseHost,
|
|
86
|
-
)}
|
|
87
|
-
method="get"
|
|
88
|
-
@submit=${this.search}
|
|
89
|
-
data-event-submit-tracking="${this.config
|
|
90
|
-
?.eventCategory}|NavSearchSubmit"
|
|
91
|
-
>
|
|
92
|
-
<label for="query" class="sr-only">Search the Archive</label>
|
|
93
|
-
<input
|
|
94
|
-
type="text"
|
|
95
|
-
name="query"
|
|
96
|
-
id="query"
|
|
97
|
-
class="search-field"
|
|
98
|
-
placeholder="Search"
|
|
99
|
-
autocomplete="off"
|
|
100
|
-
value=${this.searchQuery || ''}
|
|
101
|
-
@focus=${this.toggleSearchMenu}
|
|
102
|
-
/>
|
|
103
|
-
${this.searchInsideInput}
|
|
104
|
-
<button
|
|
105
|
-
type="submit"
|
|
106
|
-
class="search"
|
|
107
|
-
tabindex="-1"
|
|
108
|
-
data-event-click-tracking="${this.config
|
|
109
|
-
?.eventCategory}|NavSearchClose"
|
|
110
|
-
>
|
|
111
|
-
${icons.search}
|
|
112
|
-
</button>
|
|
113
|
-
</form>
|
|
114
|
-
</div>
|
|
115
|
-
`;
|
|
116
|
-
}
|
|
117
|
-
}
|
package/src/search-menu.ts
DELETED
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
import { html } from 'lit';
|
|
2
|
-
import { customElement, property } from 'lit/decorators.js';
|
|
3
|
-
|
|
4
|
-
import TrackedElement from './tracked-element';
|
|
5
|
-
import searchMenuCSS from './styles/search-menu';
|
|
6
|
-
import formatUrl from './lib/format-url';
|
|
7
|
-
import { IATopNavConfig } from './models';
|
|
8
|
-
import { defaultTopNavConfig } from './data/menus';
|
|
9
|
-
|
|
10
|
-
@customElement('search-menu')
|
|
11
|
-
export class SearchMenu extends TrackedElement {
|
|
12
|
-
@property({ type: String }) baseHost = '';
|
|
13
|
-
@property({ type: Object }) config: IATopNavConfig = defaultTopNavConfig;
|
|
14
|
-
@property({ type: Boolean }) hideSearch = false;
|
|
15
|
-
@property({ type: String }) openMenu = '';
|
|
16
|
-
@property({ type: Boolean }) searchMenuOpen = false;
|
|
17
|
-
@property({ type: Boolean }) searchMenuAnimate = false;
|
|
18
|
-
@property({ type: String }) selectedSearchType = '';
|
|
19
|
-
|
|
20
|
-
static get styles() {
|
|
21
|
-
return searchMenuCSS;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
firstUpdated() {
|
|
25
|
-
this.shadowRoot?.addEventListener('keydown', (e) =>
|
|
26
|
-
this.handleKeyDownEvent(e as KeyboardEvent),
|
|
27
|
-
);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
disconnectedCallback() {
|
|
31
|
-
// Clean up event listener when the element is removed
|
|
32
|
-
this.shadowRoot?.removeEventListener('keydown', (e) =>
|
|
33
|
-
this.handleKeyDownEvent(e as KeyboardEvent),
|
|
34
|
-
);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
private handleKeyDownEvent(e: KeyboardEvent) {
|
|
38
|
-
if (!this.shadowRoot) return;
|
|
39
|
-
|
|
40
|
-
const searchTypes = this.shadowRoot.querySelectorAll(
|
|
41
|
-
'.search-menu-inner label input[type=radio]',
|
|
42
|
-
) as NodeListOf<HTMLInputElement>;
|
|
43
|
-
|
|
44
|
-
const length = searchTypes.length - 1;
|
|
45
|
-
if (!length) return;
|
|
46
|
-
|
|
47
|
-
const searchTypeHandler = (index: number) => {
|
|
48
|
-
e.preventDefault();
|
|
49
|
-
const searchType = searchTypes[index];
|
|
50
|
-
searchType.checked = true;
|
|
51
|
-
searchType.dispatchEvent(new Event('change'));
|
|
52
|
-
searchType.focus();
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
if (e.key === 'Home') {
|
|
56
|
-
searchTypeHandler(0);
|
|
57
|
-
} else if (e.key === 'End') {
|
|
58
|
-
searchTypeHandler(length);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
selectSearchType(e: Event) {
|
|
63
|
-
const target = e.target as HTMLInputElement;
|
|
64
|
-
this.selectedSearchType = target.value;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
searchInChanged(e: InputEvent) {
|
|
68
|
-
const target = e.target as HTMLInputElement;
|
|
69
|
-
this.dispatchEvent(
|
|
70
|
-
new CustomEvent('searchInChanged', {
|
|
71
|
-
detail: {
|
|
72
|
-
searchIn: target.value,
|
|
73
|
-
},
|
|
74
|
-
}),
|
|
75
|
-
);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
get searchTypesTemplate() {
|
|
79
|
-
const searchTypes = [
|
|
80
|
-
{
|
|
81
|
-
label: 'metadata',
|
|
82
|
-
value: '',
|
|
83
|
-
isDefault: true,
|
|
84
|
-
},
|
|
85
|
-
{
|
|
86
|
-
label: 'text contents',
|
|
87
|
-
value: 'TXT',
|
|
88
|
-
},
|
|
89
|
-
{
|
|
90
|
-
label: 'TV news captions',
|
|
91
|
-
value: 'TV',
|
|
92
|
-
},
|
|
93
|
-
{
|
|
94
|
-
label: 'radio transcripts',
|
|
95
|
-
value: 'RADIO',
|
|
96
|
-
},
|
|
97
|
-
{
|
|
98
|
-
label: 'archived web sites',
|
|
99
|
-
value: 'WEB',
|
|
100
|
-
},
|
|
101
|
-
].map(({ value, label, isDefault }) => {
|
|
102
|
-
if (
|
|
103
|
-
this.config.hiddenSearchOptions &&
|
|
104
|
-
this.config.hiddenSearchOptions.includes(value)
|
|
105
|
-
) {
|
|
106
|
-
return html``;
|
|
107
|
-
}
|
|
108
|
-
return html`
|
|
109
|
-
<label @click="${this.selectSearchType}">
|
|
110
|
-
<input
|
|
111
|
-
form="nav-search"
|
|
112
|
-
type="radio"
|
|
113
|
-
name="sin"
|
|
114
|
-
value="${value}"
|
|
115
|
-
?checked=${isDefault}
|
|
116
|
-
?disabled=${!this.openMenu}
|
|
117
|
-
@change=${this.searchInChanged}
|
|
118
|
-
/>
|
|
119
|
-
Search ${label}
|
|
120
|
-
</label>
|
|
121
|
-
`;
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
return searchTypes;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
get menuClass() {
|
|
128
|
-
return this.openMenu === 'search' ? 'open' : 'closed';
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
render() {
|
|
132
|
-
if (this.hideSearch) {
|
|
133
|
-
return html``;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
return html`
|
|
137
|
-
<div class="menu-wrapper">
|
|
138
|
-
<div
|
|
139
|
-
class="search-menu-inner tx-slide ${this.menuClass}"
|
|
140
|
-
aria-hidden="${!this.openMenu}"
|
|
141
|
-
>
|
|
142
|
-
${this.searchTypesTemplate}
|
|
143
|
-
<a
|
|
144
|
-
class="advanced-search"
|
|
145
|
-
href="${formatUrl('/advancedsearch.php', this.baseHost)}"
|
|
146
|
-
@click=${this.trackClick}
|
|
147
|
-
tabindex=${this.openMenu ? '0' : '-1'}
|
|
148
|
-
data-event-click-tracking="${this.config
|
|
149
|
-
.eventCategory}|NavAdvancedSearch"
|
|
150
|
-
>Advanced Search</a
|
|
151
|
-
>
|
|
152
|
-
</div>
|
|
153
|
-
</div>
|
|
154
|
-
`;
|
|
155
|
-
}
|
|
156
|
-
}
|