@zanichelli/zanichelli-it-frontend-kit 1.1.2-RC → 1.3.0-RC1
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/dist/cjs/{index-q1XSBSqA.js → index-CRwLFnL1.js} +7 -3
- package/dist/cjs/index-CRwLFnL1.js.map +1 -0
- package/dist/cjs/loader.cjs.js +2 -2
- package/dist/cjs/zanichelli-it-frontend-kit.cjs.js +2 -2
- package/dist/cjs/zanit-menubar.zanit-mobile-menubar.zanit-search-form.entry.cjs.js.map +1 -1
- package/dist/cjs/zanit-menubar_3.cjs.entry.js +267 -22
- package/dist/cjs/zanit-menubar_3.cjs.entry.js.map +1 -1
- package/dist/collection/components/menubar/menubar.css +1 -0
- package/dist/collection/components/menubar/menubar.js +53 -2
- package/dist/collection/components/menubar/menubar.js.map +1 -1
- package/dist/collection/components/menubar/mobile-menubar/mobile-menubar.js +52 -1
- package/dist/collection/components/menubar/mobile-menubar/mobile-menubar.js.map +1 -1
- package/dist/collection/components/menubar/search-form/search-form.css +45 -0
- package/dist/collection/components/menubar/search-form/search-form.js +208 -22
- package/dist/collection/components/menubar/search-form/search-form.js.map +1 -1
- package/dist/collection/components/menubar/search-form/suggestions.js +84 -0
- package/dist/collection/components/menubar/search-form/suggestions.js.map +1 -0
- package/dist/collection/utils/subjects.api.js +25 -0
- package/dist/collection/utils/subjects.api.js.map +1 -0
- package/dist/collection/utils/utils.js +8 -0
- package/dist/collection/utils/utils.js.map +1 -1
- package/dist/components/index.js +5 -2
- package/dist/components/index.js.map +1 -1
- package/dist/components/{p-DCsoOA4v.js → p-CuXV3NdC.js} +12 -5
- package/dist/components/p-CuXV3NdC.js.map +1 -0
- package/dist/components/p-DRtCn2AS.js +376 -0
- package/dist/components/p-DRtCn2AS.js.map +1 -0
- package/dist/components/zanit-menubar.js +13 -6
- package/dist/components/zanit-menubar.js.map +1 -1
- package/dist/components/zanit-mobile-menubar.js +1 -1
- package/dist/components/zanit-search-form.js +1 -1
- package/dist/esm/{index-CaWL2omE.js → index-B82IapZZ.js} +7 -4
- package/dist/esm/index-B82IapZZ.js.map +1 -0
- package/dist/esm/loader.js +3 -3
- package/dist/esm/zanichelli-it-frontend-kit.js +3 -3
- package/dist/esm/zanit-menubar.zanit-mobile-menubar.zanit-search-form.entry.js.map +1 -1
- package/dist/esm/zanit-menubar_3.entry.js +267 -22
- package/dist/esm/zanit-menubar_3.entry.js.map +1 -1
- package/dist/types/components/menubar/menubar.d.ts +5 -0
- package/dist/types/components/menubar/mobile-menubar/mobile-menubar.d.ts +5 -0
- package/dist/types/components/menubar/search-form/search-form.d.ts +28 -5
- package/dist/types/components/menubar/search-form/suggestions.d.ts +11 -0
- package/dist/types/components.d.ts +60 -4
- package/dist/types/utils/subjects.api.d.ts +6 -0
- package/dist/types/utils/types.d.ts +7 -0
- package/dist/types/utils/utils.d.ts +8 -0
- package/{www/build/p-CaWL2omE.js → dist/zanichelli-it-frontend-kit/p-B82IapZZ.js} +2 -2
- package/dist/zanichelli-it-frontend-kit/p-B82IapZZ.js.map +1 -0
- package/dist/zanichelli-it-frontend-kit/p-d7e08556.entry.js +2 -0
- package/dist/zanichelli-it-frontend-kit/p-d7e08556.entry.js.map +1 -0
- package/dist/zanichelli-it-frontend-kit/zanichelli-it-frontend-kit.esm.js +1 -1
- package/dist/zanichelli-it-frontend-kit/zanit-menubar.zanit-mobile-menubar.zanit-search-form.entry.esm.js.map +1 -1
- package/package.json +11 -12
- package/www/build/p-3c83769f.js +2 -0
- package/{dist/zanichelli-it-frontend-kit/p-CaWL2omE.js → www/build/p-B82IapZZ.js} +2 -2
- package/www/build/p-B82IapZZ.js.map +1 -0
- package/www/build/p-d7e08556.entry.js +2 -0
- package/www/build/p-d7e08556.entry.js.map +1 -0
- package/www/build/zanichelli-it-frontend-kit.esm.js +1 -1
- package/www/build/zanit-menubar.zanit-mobile-menubar.zanit-search-form.entry.esm.js.map +1 -1
- package/www/index.html +1 -1
- package/dist/cjs/index-q1XSBSqA.js.map +0 -1
- package/dist/components/p-C_SXGfG9.js +0 -133
- package/dist/components/p-C_SXGfG9.js.map +0 -1
- package/dist/components/p-DCsoOA4v.js.map +0 -1
- package/dist/esm/index-CaWL2omE.js.map +0 -1
- package/dist/zanichelli-it-frontend-kit/p-217f87ff.entry.js +0 -2
- package/dist/zanichelli-it-frontend-kit/p-217f87ff.entry.js.map +0 -1
- package/dist/zanichelli-it-frontend-kit/p-CaWL2omE.js.map +0 -1
- package/www/build/p-1d74b708.js +0 -2
- package/www/build/p-217f87ff.entry.js +0 -2
- package/www/build/p-217f87ff.entry.js.map +0 -1
- package/www/build/p-CaWL2omE.js.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var index = require('./index-
|
|
3
|
+
var index = require('./index-CRwLFnL1.js');
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Check if an element contains an event target by checking its composedPath.
|
|
@@ -18,6 +18,14 @@ const moveFocus = (current, next) => {
|
|
|
18
18
|
next.tabIndex = 0;
|
|
19
19
|
next.focus({ preventScroll: true });
|
|
20
20
|
};
|
|
21
|
+
/** Check if event key is ArrowUp */
|
|
22
|
+
const isArrowUpKey = (event) => event.key === 'ArrowUp';
|
|
23
|
+
/** Check if event key is ArrowDown */
|
|
24
|
+
const isArrowDownKey = (event) => event.key === 'ArrowDown';
|
|
25
|
+
/** Check if event key is Tab */
|
|
26
|
+
const isTabKey = (event) => event.key === 'Tab';
|
|
27
|
+
/** Check if event key is Escape */
|
|
28
|
+
const isEscKey = (event) => event.key === 'Escape';
|
|
21
29
|
|
|
22
30
|
const DEFAULT_GROUP_KEY = 'default';
|
|
23
31
|
const DEFAULT_GROUP = {
|
|
@@ -59,7 +67,32 @@ const Menu = ({ controlledBy, items, currentPath = [], onItemKeyDown }) => {
|
|
|
59
67
|
}, href: item.href, role: "menuitem", tabIndex: -1, "aria-current": isActive(item) ? 'page' : 'false', onKeyDown: (event) => onItemKeyDown(event), target: item.target }, item.label))))))))))));
|
|
60
68
|
};
|
|
61
69
|
|
|
62
|
-
|
|
70
|
+
var SearchEnv;
|
|
71
|
+
(function (SearchEnv) {
|
|
72
|
+
SearchEnv["DEV"] = "dev";
|
|
73
|
+
SearchEnv["TEST"] = "test";
|
|
74
|
+
SearchEnv["PROD"] = "prod";
|
|
75
|
+
})(SearchEnv || (SearchEnv = {}));
|
|
76
|
+
const S3_SHOP_URL = {
|
|
77
|
+
dev: 'https://zanichelli-shop-dev.s3.eu-west-1.amazonaws.com',
|
|
78
|
+
test: 'https://zanichelli-shop-test.s3.eu-west-1.amazonaws.com',
|
|
79
|
+
prod: 'https://zanichelli-shop.s3.eu-west-1.amazonaws.com',
|
|
80
|
+
};
|
|
81
|
+
async function getSubjectsByArea(searchEnv) {
|
|
82
|
+
try {
|
|
83
|
+
const response = await fetch(`${S3_SHOP_URL[searchEnv]}/categories.json`);
|
|
84
|
+
if (!response.ok) {
|
|
85
|
+
throw new Error(`HTTP ${response.status}`);
|
|
86
|
+
}
|
|
87
|
+
return await response.json();
|
|
88
|
+
}
|
|
89
|
+
catch (err) {
|
|
90
|
+
console.error('Error fetching subjects:', err);
|
|
91
|
+
return {};
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const menubarCss = ":host{position:relative;z-index:2;display:flex;width:100%;background-color:#fff;color:var(--gray900);font-family:var(--font-family-sans)}:host,*,::before,::after{box-sizing:border-box}*:focus:focus-visible{box-shadow:var(--shadow-focus-primary);outline:none}ul{padding:0;margin:0;list-style:none}a{color:var(--gray900);cursor:pointer;text-decoration:none}button{all:unset;cursor:pointer}:host nav{width:100%}.shadow-wrapper{position:relative;z-index:1;display:flex;width:100%}.shadow-wrapper::after{position:absolute;top:0;right:0;width:100%;height:100%;background:transparent;box-shadow:var(--shadow-1);content:'';pointer-events:none}.width-limiter{position:relative;display:flex;width:100%;max-width:var(--zanit-menubar-max-width, 1366px);margin:0 auto}.shadow-wrapper+.shadow-wrapper{z-index:0}.sub-menubar>ul{gap:28px}.width-limiter>ul,.sub-menubar>ul{position:relative;z-index:3;display:flex;width:100%;align-items:center;padding:0 var(--grid-margin);margin-right:auto;margin-left:auto;gap:20px}.shadow-wrapper>.width-limiter,.shadow-wrapper>ul{width:100%;max-width:var(--zanit-menubar-max-width, 1366px)}ul.menubar{padding-right:0}.menubar z-ghost-loading{display:block;width:120px;height:1.25rem}.menubar>li[role='separator']{width:1px;height:1.25rem;background-color:#000}.menubar-item{position:relative;display:flex;align-items:center;padding:14px 0;font-size:1rem;gap:8px;line-height:1.25rem}.menubar .menubar-item{text-transform:uppercase}.menubar-item [data-text]{display:flex;flex-direction:column}.menubar-item.active>[data-text],.menubar-item:hover>[data-text],.menubar-item:focus:focus-visible>[data-text]{font-weight:var(--font-bd)}.menubar-item>[data-text]::after{height:0;content:attr(data-text) / '';font-weight:var(--font-bd);letter-spacing:normal;pointer-events:none;user-select:none;visibility:hidden}.sub-menubar .menubar-item.active::after{position:absolute;z-index:-1;bottom:0;left:-4px;width:calc(100% + 8px);height:4px;background-color:var(--red500);content:''}zanit-search-form{margin-left:auto}";
|
|
63
96
|
|
|
64
97
|
const menuCss$1 = ".menu-wrapper{width:100%;background-color:#fff}.menu{position:relative;display:flex;width:100%;flex-direction:column;gap:32px 0}.menu .group{display:flex;flex-direction:column}.menu .group .group-name{border-bottom:1px solid currentcolor;margin-bottom:4px;color:var(--red500);font-size:0.875rem;font-weight:var(--font-md)}.menu .group .menu-list{display:flex;flex-direction:column;gap:8px}.menu .group .menu-list .menu-item{display:block;border-bottom:2px solid transparent;font-size:0.875rem;font-weight:var(--font-md)}.menu .menu-list .menu-item.active,.menu .menu-list .menu-item:hover{border-bottom-color:var(--red500)}.menu .group.highlight .menu-list .menu-item{font-size:1rem}@media (width >= 768px){.menu-wrapper{position:absolute;top:100%;left:0;display:flex;justify-content:center;box-shadow:var(--shadow-1)}.menu{display:grid;width:100%;max-width:var(--zanit-menubar-max-width, 1366px);padding:16px var(--grid-margin);gap:0 24px;grid-auto-columns:minmax(0, max-content);grid-auto-flow:column;grid-template-rows:minmax(0, max-content) max-content}.menu .group{display:grid;grid-row:1 / -1;grid-template-columns:1fr;grid-template-rows:subgrid}@supports not (grid-template-rows: subgrid){.menu .group{grid-template-rows:repeat(auto-fit, minmax(0, max-content))}}.menu .group .group-name{border:none;margin-bottom:16px}.menu .group .menu-list .menu-item{font-size:1rem}.menu .group.highlight .menu-list .menu-item{font-size:1.5rem}}";
|
|
65
98
|
|
|
@@ -84,6 +117,10 @@ const ZanitMenubar = class {
|
|
|
84
117
|
current = undefined;
|
|
85
118
|
/** Initial search query. */
|
|
86
119
|
searchQuery = undefined;
|
|
120
|
+
/** Environment for search suggestions */
|
|
121
|
+
searchEnv = SearchEnv.PROD;
|
|
122
|
+
/** Search area (e.g. "SCUOLA", "UNIVERSITÀ", "DIZIONARI"). */
|
|
123
|
+
searchArea;
|
|
87
124
|
timerId;
|
|
88
125
|
/** Setup the list of items. */
|
|
89
126
|
async parseData(data) {
|
|
@@ -435,19 +472,20 @@ const ZanitMenubar = class {
|
|
|
435
472
|
}
|
|
436
473
|
render() {
|
|
437
474
|
if (this.isMobile) {
|
|
438
|
-
return (index.h("zanit-mobile-menubar", { items: this.items, currentPath: this.currentPath, searchQuery: this.searchQuery, loading: this.loading }));
|
|
475
|
+
return (index.h("zanit-mobile-menubar", { items: this.items, currentPath: this.currentPath, searchQuery: this.searchQuery, loading: this.loading, searchArea: this.searchArea, searchEnv: this.searchEnv }));
|
|
439
476
|
}
|
|
440
477
|
return (index.h("nav", { "aria-label": "Zanichelli.it" }, index.h("div", { class: "shadow-wrapper" }, index.h("div", { class: "width-limiter" }, index.h("ul", { class: "menubar", role: "menubar", "aria-label": "Zanichelli.it" }, this.loading &&
|
|
441
478
|
[...new Array(4)].map((_, index$1) => (index.h(index.Fragment, null, index.h("li", { role: "none" }, index.h("div", { class: "menubar-item" }, index.h("z-ghost-loading", null))), index$1 < 3 && index.h("li", { role: "separator" })))), this.items?.map((item, index$1) => (index.h(index.Fragment, null, index.h("li", { role: "none" }, index.h("a", { class: {
|
|
442
479
|
'menubar-item': true,
|
|
443
480
|
'active': this.isActive(item),
|
|
444
|
-
}, href: item.href, id: item.id, role: "menuitem", tabIndex: -1, "aria-expanded": item.menuItems?.length ? (this.openMenu === item.id ? 'true' : 'false') : undefined, "aria-haspopup": item.menuItems?.length ? 'true' : 'false', "aria-current": this.current.includes(item.id) ? 'page' : 'false', onPointerOver: () => this.showMenu(item), onKeyDown: (event) => this.handleItemKeydown(event, item), target: item.target }, index.h("span", { "data-text": item.label }, item.label), item.menuItems?.length > 0 && (index.h("z-icon", { name: this.openMenu === item.id ? 'chevron-up' : 'chevron-down', width: "0.875rem", height: "0.875rem" })))), index$1 < this.items?.length - 1 && index.h("li", { role: "separator" }))))), index.h("zanit-search-form", { searchQuery: this.searchQuery, onResetSearch: () => (this.searchQuery = undefined) })), this.items.map((item) => this.openMenu === item.id && (index.h(Menu, { controlledBy: item.id, items: item.menuItems, currentPath: this.currentPath, onItemKeyDown: (event) => this.handleMenuKeydown(event) })))), this.items
|
|
481
|
+
}, href: item.href, id: item.id, role: "menuitem", tabIndex: -1, "aria-expanded": item.menuItems?.length ? (this.openMenu === item.id ? 'true' : 'false') : undefined, "aria-haspopup": item.menuItems?.length ? 'true' : 'false', "aria-current": this.current.includes(item.id) ? 'page' : 'false', onPointerOver: () => this.showMenu(item), onKeyDown: (event) => this.handleItemKeydown(event, item), target: item.target }, index.h("span", { "data-text": item.label }, item.label), item.menuItems?.length > 0 && (index.h("z-icon", { name: this.openMenu === item.id ? 'chevron-up' : 'chevron-down', width: "0.875rem", height: "0.875rem" })))), index$1 < this.items?.length - 1 && index.h("li", { role: "separator" }))))), index.h("zanit-search-form", { searchQuery: this.searchQuery, searchArea: this.searchArea, searchEnv: this.searchEnv, onResetSearch: () => (this.searchQuery = undefined) })), this.items.map((item) => this.openMenu === item.id && (index.h(Menu, { controlledBy: item.id, items: item.menuItems, currentPath: this.currentPath, onItemKeyDown: (event) => this.handleMenuKeydown(event) })))), this.items
|
|
445
482
|
?.filter((item) => this.isActive(item))
|
|
446
483
|
.map((item) => item.navbarItems?.length && (index.h("nav", { class: { 'sub-menubar': true, 'shadow-wrapper': true }, "aria-label": `Sezioni: ${item.label}` }, index.h("ul", { role: "menubar" }, item.navbarItems.map((subitem) => (index.h(index.Fragment, null, index.h("li", { role: "none" }, index.h("a", { class: {
|
|
447
484
|
'menubar-item': true,
|
|
448
485
|
'active': this.isActive(subitem),
|
|
449
486
|
}, href: subitem.href, id: subitem.id, role: "menuitem", tabIndex: -1, "aria-haspopup": subitem.menuItems?.length ? 'true' : 'false', "aria-expanded": subitem.menuItems?.length ? (this.openMenu === subitem.id ? 'true' : 'false') : undefined, "aria-current": this.current.includes(subitem.id) ? 'page' : 'false', onPointerOver: () => this.showMenu(subitem), onKeyDown: (event) => this.handleItemKeydown(event, subitem), target: item.target }, index.h("span", null, subitem.label), subitem.menuItems?.length > 0 && (index.h("z-icon", { name: this.openMenu === subitem.id ? 'chevron-up' : 'chevron-down', width: "0.75rem", height: "0.75rem" })))))))), item.navbarItems.map((subitem) => this.openMenu === subitem.id && (index.h(Menu, { controlledBy: subitem.id, items: subitem.menuItems, currentPath: this.currentPath, onItemKeyDown: (event) => this.handleMenuKeydown(event) }))))))));
|
|
450
487
|
}
|
|
488
|
+
static get delegatesFocus() { return true; }
|
|
451
489
|
static get watchers() { return {
|
|
452
490
|
"data": ["parseData"],
|
|
453
491
|
"items": ["onItemsChange"],
|
|
@@ -473,6 +511,10 @@ const ZanitMobileMenubar = class {
|
|
|
473
511
|
searchQuery = undefined;
|
|
474
512
|
/** Whether the menubar is loading the data. */
|
|
475
513
|
loading = false;
|
|
514
|
+
/** Environment for search suggestions */
|
|
515
|
+
searchEnv = SearchEnv.PROD;
|
|
516
|
+
/** Search area (e.g. "SCUOLA", "UNIVERSITÀ", "DIZIONARI"). */
|
|
517
|
+
searchArea;
|
|
476
518
|
/** Last active item ID. */
|
|
477
519
|
lastCurrent = undefined;
|
|
478
520
|
parentItem = undefined;
|
|
@@ -602,11 +644,12 @@ const ZanitMobileMenubar = class {
|
|
|
602
644
|
this.open = false;
|
|
603
645
|
}
|
|
604
646
|
render() {
|
|
605
|
-
return (index.h("nav", { key: '
|
|
647
|
+
return (index.h("nav", { key: 'f21d484bf0c81aa8e4583f71bf8a8523c57b791f', "aria-label": "Zanichelli.it" }, index.h("button", { key: '5331948d9f25ebf2812b9538ba2654ccd98a376a', class: "burger-button", type: "button", "aria-expanded": this.open ? 'true' : 'false', "aria-controls": "mobile-menu", "aria-label": this.open ? 'Chiudi menù' : 'Apri menù', onClick: () => this.toggleMenu() }, index.h("z-icon", { key: '14b6264bd1aa3383a90d0f38924cc73b407af7fb', name: this.open ? 'multiply' : 'burger-menu', width: "1.5rem", height: "1.5rem" })), index.h("z-logo", { key: 'ad25511bb218bdfae227a6f84c2f84790da5495a', imageAlt: "Logo Zanichelli", link: "/", height: 32, width: 126 }), index.h("zanit-search-form", { key: 'a76767d008e17c8c22baef76eb5ef6237764a665', searchQuery: this.searchQuery, onResetSearch: () => (this.searchQuery = undefined), searchArea: this.searchArea, searchEnv: this.searchEnv }), this.open && (index.h("ul", { key: 'dc7159a8a0342825a7828323204dd10e32ea30ee', class: "mobile-menu", role: "menubar" }, !this.loading && this.currentPath && this.currentPath.length > 0 && (index.h("li", { key: '60f03b21375d3cdc89242a67b89c42a6d2aad5ca', role: "none" }, index.h("a", { key: '143c13385480d4860d95cc073af0d53aa8f622f2', class: "parent", href: this.parentItem?.href ?? '/', id: this.parentItem?.id ?? undefined, role: "menuitem", tabIndex: -1, onKeyDown: (event) => this.handleItemKeydown(event), target: this.parentItem?.target }, index.h("z-icon", { key: 'a433613bd001bcbd44ba98305291d8d585349f21', name: "arrow-left", width: "0.5rem", height: "0.5rem" }), index.h("span", { key: '237cc68a00c57e71ef564444ab872a4d47bf7071' }, this.parentItem?.label || 'Home')))), this.loading ? (index.h("div", { class: "items-container", role: "none" }, [...new Array(4)].map(() => (index.h("li", { role: "none" }, index.h("div", { class: "menubar-item", role: "none" }, index.h("z-ghost-loading", null))))))) : this.menuType === 'menu' ? (index.h(Menu, { items: this.menuItems, controlledBy: this.parentItem?.id, currentPath: this.currentPath, onItemKeyDown: (event) => this.handleItemKeydown(event) })) : (this.menuItems?.length > 0 && (index.h("div", { class: "items-container", role: "none" }, this.menuItems.map((item) => (index.h("li", { role: "none" }, index.h("a", { class: {
|
|
606
648
|
'menu-item': this.menuType === 'menu',
|
|
607
649
|
'menubar-item': this.menuType === 'menubar',
|
|
608
650
|
}, href: item.href, id: item.id, role: "menuitem", "aria-current": this.lastCurrent === item.id ? 'page' : 'false', tabIndex: -1, onKeyDown: (event) => this.handleItemKeydown(event), target: item.target }, index.h("span", { "data-text": item.label }, item.label))))))))))));
|
|
609
651
|
}
|
|
652
|
+
static get delegatesFocus() { return true; }
|
|
610
653
|
static get watchers() { return {
|
|
611
654
|
"items": ["onItemsChange"],
|
|
612
655
|
"currentPath": ["onItemsChange"]
|
|
@@ -614,7 +657,91 @@ const ZanitMobileMenubar = class {
|
|
|
614
657
|
};
|
|
615
658
|
ZanitMobileMenubar.style = mobileMenubarCss + menuCss;
|
|
616
659
|
|
|
617
|
-
|
|
660
|
+
var AREA_LABELS;
|
|
661
|
+
(function (AREA_LABELS) {
|
|
662
|
+
AREA_LABELS["SCUOLA"] = "Scuola";
|
|
663
|
+
AREA_LABELS["UNIVERSIT\u00C0"] = "Universit\u00E0";
|
|
664
|
+
AREA_LABELS["GIURIDICO"] = "Giuridico";
|
|
665
|
+
AREA_LABELS["DIZIONARI"] = "Dizionari";
|
|
666
|
+
AREA_LABELS["SAGGISTICA"] = "Saggistica";
|
|
667
|
+
})(AREA_LABELS || (AREA_LABELS = {}));
|
|
668
|
+
const AREA_ORDER = Object.keys(AREA_LABELS);
|
|
669
|
+
function buildSuggestions(query, subjectsByArea, selectedArea) {
|
|
670
|
+
const matchingSubjectAreas = findSubjectAreas(query, subjectsByArea);
|
|
671
|
+
const hasSubject = matchingSubjectAreas.length > 0;
|
|
672
|
+
const subject = hasSubject ? query.toUpperCase() : undefined;
|
|
673
|
+
const suggestions = [];
|
|
674
|
+
if (selectedArea)
|
|
675
|
+
suggestions.push(buildWordSuggestion(query, selectedArea));
|
|
676
|
+
suggestions.push(buildWordSuggestion(query));
|
|
677
|
+
if (hasSubject) {
|
|
678
|
+
if (selectedArea) {
|
|
679
|
+
const orderedSubjectAreas = [
|
|
680
|
+
...matchingSubjectAreas.filter((area) => area === selectedArea),
|
|
681
|
+
...matchingSubjectAreas
|
|
682
|
+
.filter((area) => area !== selectedArea)
|
|
683
|
+
.sort((a, b) => getAreaOrder(a) - getAreaOrder(b)),
|
|
684
|
+
];
|
|
685
|
+
orderedSubjectAreas.forEach((area) => suggestions.push(buildSubjectSuggestion(query, area, subject)));
|
|
686
|
+
}
|
|
687
|
+
else {
|
|
688
|
+
matchingSubjectAreas
|
|
689
|
+
.sort((a, b) => getAreaOrder(a) - getAreaOrder(b))
|
|
690
|
+
.forEach((subjectArea) => suggestions.push(buildSubjectSuggestion(query, subjectArea, subject)));
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
return suggestions;
|
|
694
|
+
}
|
|
695
|
+
const buildWordSuggestion = (user_query, area) => {
|
|
696
|
+
return {
|
|
697
|
+
id: buildId(`word-${user_query}-${area}`),
|
|
698
|
+
label: buildLabel(user_query, area, false, false),
|
|
699
|
+
html_label: buildLabel(user_query, area, false, true),
|
|
700
|
+
url: buildUrl({ q: user_query, ...(area ? { area } : {}), user_query }),
|
|
701
|
+
...buildDetail(user_query, user_query, area),
|
|
702
|
+
};
|
|
703
|
+
};
|
|
704
|
+
const buildSubjectSuggestion = (user_query, area, subject) => {
|
|
705
|
+
return {
|
|
706
|
+
id: buildId(`subj-${user_query}-${area}-${subject}`),
|
|
707
|
+
label: buildLabel(user_query, area, true, false),
|
|
708
|
+
html_label: buildLabel(user_query, area, true, true),
|
|
709
|
+
url: buildUrl({ area, materia: subject, user_query }),
|
|
710
|
+
...buildDetail(user_query, undefined, area, subject),
|
|
711
|
+
};
|
|
712
|
+
};
|
|
713
|
+
const buildId = (string) => string
|
|
714
|
+
.split('')
|
|
715
|
+
.map((c) => c.charCodeAt(0).toString(16))
|
|
716
|
+
.join('');
|
|
717
|
+
const buildUrl = (params) => {
|
|
718
|
+
return `ricerca?${new URLSearchParams(params).toString()}`;
|
|
719
|
+
};
|
|
720
|
+
const buildDetail = (user_query, query, area, subject) => ({
|
|
721
|
+
user_query,
|
|
722
|
+
...(query ? { query } : {}),
|
|
723
|
+
...(area ? { area } : {}),
|
|
724
|
+
...(subject ? { subject } : {}),
|
|
725
|
+
});
|
|
726
|
+
const buildLabel = (user_query, area, isSubject = false, isHtml = false) => {
|
|
727
|
+
const openStrong = isHtml ? `<strong>` : ``;
|
|
728
|
+
const closeStrong = isHtml ? `</strong>` : ``;
|
|
729
|
+
return `Cerca la ${isSubject ? `materia` : `parola`} ${openStrong}${user_query}${closeStrong} ${area ? `nel catalogo ${openStrong}${AREA_LABELS[area] ?? area}` : `in tutto il sito`}${closeStrong}`;
|
|
730
|
+
};
|
|
731
|
+
function findSubjectAreas(query, subjectsByArea) {
|
|
732
|
+
const cleanedQuery = cleanSearch(query);
|
|
733
|
+
return Object.entries(subjectsByArea)
|
|
734
|
+
.filter(([, subjects]) => subjects.some((subject) => subject.toLowerCase() === cleanedQuery))
|
|
735
|
+
.map(([area]) => area);
|
|
736
|
+
}
|
|
737
|
+
/** Clear search string: lowercase, remove multiple spaces */
|
|
738
|
+
const cleanSearch = (s) => s.toLowerCase().replace(/\s+/g, ' ');
|
|
739
|
+
const getAreaOrder = (area) => {
|
|
740
|
+
const index = AREA_ORDER.indexOf(area);
|
|
741
|
+
return index >= 0 ? index : 100;
|
|
742
|
+
};
|
|
743
|
+
|
|
744
|
+
const searchFormCss = ":host,*,::before,::after{box-sizing:border-box}*:focus:focus-visible{box-shadow:var(--shadow-focus-primary);outline:none}button{all:unset;cursor:pointer}.searchbar{--searchbar-button-x-padding:14px;--searchbar-button-icon-width:1.75rem;--closed-searchbar-width:calc((var(--searchbar-button-x-padding) * 2) + var(--searchbar-button-icon-width) + 1px);position:absolute;z-index:5;top:0;right:0;display:flex;width:var(--closed-searchbar-width);justify-content:flex-end;transition:width 0.4s ease-in-out}.searchbar.searchbar-open{width:100%}.searchbar .input-wrapper{display:flex;overflow:hidden;width:100%;align-items:center;padding:8px;padding-left:var(--grid-margin);background-color:#fff;gap:8px;transition-duration:0.4s;transition-property:padding-right, padding-left, width;transition-timing-function:ease-in-out}.searchbar:not(.searchbar-open) .input-wrapper{overflow:hidden;width:0;padding:0}.searchbar button[type='reset']{--z-icon-width:1rem;--z-icon-height:1rem;display:flex;align-items:center;cursor:pointer}.searchbar input{z-index:1;width:100%;height:100%;padding:0;border:none;background-color:#fff;font-family:var(--font-family-sans);font-size:1rem}.searchbar.searchbar-open input:first-child{padding-left:4px;margin-left:-4px;}.searchbar input[type='search']::-webkit-search-cancel-button,.searchbar input[type='search']::-webkit-search-decoration{appearance:none}.searchbar input::placeholder{color:var(--gray500)}.searchbar .searchbar-button{display:flex;align-items:center;justify-content:center;padding:10px var(--searchbar-button-x-padding);border-left:1px solid #000;background:var(--zanit-accent-color);font-family:inherit;font-size:inherit;gap:64px;line-height:1}.searchbar .searchbar-button:focus-visible{z-index:1}.searchbar-button z-icon{--z-icon-width:var(--searchbar-button-icon-width);--z-icon-height:var(--searchbar-button-icon-width)}.suggestions-wrapper{position:absolute;z-index:4;width:100vw;margin-left:-50vw;left:50%;top:48px;background:#fff;box-shadow:var(--shadow-1);border-top:1px solid var(--gray200)}.suggestions-wrapper.hidden{display:none}.suggestions{display:flex;padding:var(--space-unit);flex-direction:column;align-items:stretch;width:100%;margin:0 auto}.suggestion{cursor:pointer;padding:calc(var(--space-unit) * 0.75) var(--space-unit)}.suggestion:hover,.suggestion[aria-selected='true']{background:var(--gray100)}@media (width < 1152px){.searchbar .searchbar-button>.searchbar-button-label{display:none}}@media (width >= 768px){.searchbar{--searchbar-button-x-padding:16px;--searchbar-button-icon-width:2rem}.searchbar .input-wrapper{gap:14px}.searchbar button[type='reset']{--z-icon-width:1.5rem;--z-icon-height:1.5rem}.searchbar input,.searchbar .searchbar-button{font-size:1.5rem}.searchbar .searchbar-button{padding:8px var(--searchbar-button-x-padding)}.suggestions{padding:var(--space-unit) calc(var(--space-unit) * 2)}}@media (width >= 1152px){.searchbar{--closed-searchbar-width:190px}}@media (width >= 1366px){.searchbar .searchbar-button{border-right:1px solid #000}.suggestions{padding:var(--space-unit) calc(var(--space-unit) * 3);max-width:1366px}}";
|
|
618
745
|
|
|
619
746
|
const ZanitSearchForm = class {
|
|
620
747
|
constructor(hostRef) {
|
|
@@ -623,44 +750,77 @@ const ZanitSearchForm = class {
|
|
|
623
750
|
this.resetSearch = index.createEvent(this, "resetSearch");
|
|
624
751
|
}
|
|
625
752
|
formElement;
|
|
753
|
+
subjectsByArea = {};
|
|
754
|
+
timer;
|
|
626
755
|
get host() { return index.getElement(this); }
|
|
627
756
|
/** Indicates whether the searchbar is visible and usable. */
|
|
628
757
|
showSearchbar = false;
|
|
629
758
|
/** Search query to apply. */
|
|
630
759
|
_searchQuery = undefined;
|
|
760
|
+
/** Search suggestions to show in the autocomplete dropdown. */
|
|
761
|
+
suggestions = [];
|
|
762
|
+
/** Active suggestion - used for keyboard navigation */
|
|
763
|
+
activeSuggestion = '';
|
|
764
|
+
/** Show suggestions list */
|
|
765
|
+
showSuggestions = false;
|
|
631
766
|
/** Initial search query */
|
|
632
767
|
searchQuery = undefined;
|
|
768
|
+
/** Environment for search suggestions */
|
|
769
|
+
searchEnv = SearchEnv.PROD;
|
|
770
|
+
/** Search area (e.g. "SCUOLA", "UNIVERSITÀ", "DIZIONARI"). */
|
|
771
|
+
searchArea;
|
|
633
772
|
onSearchQueryChange() {
|
|
634
773
|
this._searchQuery = this.searchQuery;
|
|
635
774
|
if (this.searchQuery) {
|
|
636
775
|
this.openSearchbar();
|
|
637
776
|
}
|
|
777
|
+
this.resetSuggestions();
|
|
778
|
+
}
|
|
779
|
+
onSearchAreaChange() {
|
|
780
|
+
this.resetSuggestions();
|
|
781
|
+
}
|
|
782
|
+
onShowSearchbarChange() {
|
|
783
|
+
if (!this.showSearchbar) {
|
|
784
|
+
this.showSuggestions = false;
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
onShowSuggestionsChange() {
|
|
788
|
+
this.activeSuggestion = '';
|
|
638
789
|
}
|
|
639
790
|
/** Emitted on search form submission. */
|
|
640
791
|
search;
|
|
641
792
|
resetSearch;
|
|
642
793
|
async connectedCallback() {
|
|
794
|
+
this.subjectsByArea = await getSubjectsByArea(this.searchEnv);
|
|
643
795
|
this.showSearchbar = !!this.searchQuery;
|
|
644
796
|
this._searchQuery = this.searchQuery;
|
|
645
797
|
}
|
|
646
798
|
/** Close open searchbar when clicking outside. */
|
|
647
799
|
handleOutsideClick(event) {
|
|
648
|
-
if (this.showSearchbar && this.
|
|
800
|
+
if (this.showSearchbar && this.host && !containsTarget(this.host, event)) {
|
|
649
801
|
this.showSearchbar = false;
|
|
650
802
|
}
|
|
651
803
|
}
|
|
652
|
-
/** Close the
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
804
|
+
/** Close the searchbar/suggestions when pressing Escape. */
|
|
805
|
+
handleEsc(event) {
|
|
806
|
+
if (!isEscKey(event)) {
|
|
807
|
+
return;
|
|
808
|
+
}
|
|
809
|
+
if (this.showSuggestions) {
|
|
810
|
+
this.showSuggestions = false;
|
|
811
|
+
}
|
|
812
|
+
else {
|
|
813
|
+
this.showSearchbar = false;
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
/** Close the searchbar/suggestions when pressing Tab. */
|
|
817
|
+
handleTab(event) {
|
|
818
|
+
if (!isTabKey(event)) {
|
|
819
|
+
return;
|
|
820
|
+
}
|
|
821
|
+
this.showSuggestions = false;
|
|
822
|
+
if (!containsTarget(this.host, event)) {
|
|
823
|
+
this.showSearchbar = false;
|
|
664
824
|
}
|
|
665
825
|
}
|
|
666
826
|
openSearchbar() {
|
|
@@ -674,30 +834,115 @@ const ZanitSearchForm = class {
|
|
|
674
834
|
this.searchQuery = undefined;
|
|
675
835
|
this.resetSearch.emit();
|
|
676
836
|
}
|
|
837
|
+
resetSuggestions() {
|
|
838
|
+
this.suggestions = [];
|
|
839
|
+
this.showSuggestions = false;
|
|
840
|
+
}
|
|
677
841
|
handleInputChange(event) {
|
|
678
842
|
this._searchQuery = event.target.value;
|
|
679
843
|
if (!this._searchQuery) {
|
|
680
844
|
this.searchQuery = undefined;
|
|
681
845
|
}
|
|
846
|
+
this.updateSuggestions();
|
|
847
|
+
}
|
|
848
|
+
updateSuggestions() {
|
|
849
|
+
clearTimeout(this.timer);
|
|
850
|
+
const query = (this._searchQuery || '').trim();
|
|
851
|
+
if (query.length < 3) {
|
|
852
|
+
this.resetSuggestions();
|
|
853
|
+
return;
|
|
854
|
+
}
|
|
855
|
+
this.timer = setTimeout(() => {
|
|
856
|
+
this.resetSuggestions();
|
|
857
|
+
this.suggestions = buildSuggestions(query, this.subjectsByArea, this.searchArea?.toUpperCase());
|
|
858
|
+
this.showSuggestions = true;
|
|
859
|
+
}, 300);
|
|
682
860
|
}
|
|
683
861
|
onSearchSubmit(event) {
|
|
684
862
|
event.preventDefault();
|
|
685
863
|
if (!this._searchQuery) {
|
|
686
864
|
return;
|
|
687
865
|
}
|
|
866
|
+
if (this.activeSuggestion) {
|
|
867
|
+
const suggestion = this.suggestions.find((s) => s.id === this.activeSuggestion);
|
|
868
|
+
if (suggestion) {
|
|
869
|
+
this.submitSuggestionSearch(suggestion);
|
|
870
|
+
this.showSuggestions = false;
|
|
871
|
+
return;
|
|
872
|
+
}
|
|
873
|
+
}
|
|
688
874
|
this.showSearchbar = false;
|
|
689
|
-
|
|
875
|
+
this.showSuggestions = false;
|
|
876
|
+
const searchEv = this.search.emit({ query: this._searchQuery, area: this.searchArea });
|
|
690
877
|
// do not submit the form if the event default behavior was prevented
|
|
691
878
|
if (searchEv.defaultPrevented) {
|
|
692
879
|
return;
|
|
693
880
|
}
|
|
694
881
|
this.formElement.submit();
|
|
695
882
|
}
|
|
883
|
+
submitSuggestionSearch(suggestion) {
|
|
884
|
+
const ev = this.search.emit({
|
|
885
|
+
user_query: suggestion.user_query,
|
|
886
|
+
query: suggestion.query,
|
|
887
|
+
area: suggestion.area,
|
|
888
|
+
subject: suggestion.subject,
|
|
889
|
+
});
|
|
890
|
+
if (!ev.defaultPrevented) {
|
|
891
|
+
window.location.href = suggestion.url;
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
handleSuggestionsNav(event) {
|
|
895
|
+
if (!isArrowDownKey(event) && !isArrowUpKey(event)) {
|
|
896
|
+
return;
|
|
897
|
+
}
|
|
898
|
+
if (!this.suggestions.length) {
|
|
899
|
+
return;
|
|
900
|
+
}
|
|
901
|
+
const options = Array.from(this.host.shadowRoot.querySelectorAll("[role='option']")).map((o) => o.id);
|
|
902
|
+
if (!options.length) {
|
|
903
|
+
return;
|
|
904
|
+
}
|
|
905
|
+
event.preventDefault();
|
|
906
|
+
event.stopPropagation();
|
|
907
|
+
if (!this.showSuggestions) {
|
|
908
|
+
this.showSuggestions = true;
|
|
909
|
+
}
|
|
910
|
+
let nextId = null;
|
|
911
|
+
const firstId = options[0];
|
|
912
|
+
const lastId = options[options.length - 1];
|
|
913
|
+
const currOption = options.indexOf(this.activeSuggestion);
|
|
914
|
+
if (currOption < 0) {
|
|
915
|
+
nextId = isArrowDownKey(event) ? firstId : lastId;
|
|
916
|
+
}
|
|
917
|
+
else {
|
|
918
|
+
if (isArrowDownKey(event)) {
|
|
919
|
+
nextId = options[currOption + 1] || lastId;
|
|
920
|
+
}
|
|
921
|
+
else {
|
|
922
|
+
nextId = options[currOption - 1] || firstId;
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
this.activeSuggestion = nextId;
|
|
926
|
+
}
|
|
927
|
+
renderSuggestions() {
|
|
928
|
+
return (index.h("div", { class: { 'suggestions-wrapper': true, 'hidden': !this.showSuggestions || !this.suggestions.length }, onPointerOver: (e) => e.preventDefault() }, index.h("div", { id: "search-suggestions", class: "suggestions", role: "listbox", "aria-label": "Seleziona tra i suggerimenti" }, this.suggestions.map((suggestion, k) => {
|
|
929
|
+
return (index.h("span", { key: k, innerHTML: suggestion.html_label, id: suggestion.id, class: "suggestion", role: "option", "aria-label": suggestion.label, "aria-selected": this.activeSuggestion === suggestion.id ? 'true' : undefined, onClick: () => this.submitSuggestionSearch(suggestion) }));
|
|
930
|
+
}))));
|
|
931
|
+
}
|
|
696
932
|
render() {
|
|
697
|
-
return (index.h("form", { key: '
|
|
933
|
+
return (index.h(index.Host, { key: 'd7316fa36a078c2dd1c5888ba35bf004e4c08e6c' }, index.h("form", { key: '36180991431f49981a4bddd58e4caf0253f326ef', class: { 'searchbar': true, 'searchbar-open': this.showSearchbar }, ref: (el) => (this.formElement = el), role: "search", "aria-label": "Cerca nel sito", method: "get", action: "/ricerca", onSubmit: (event) => this.onSearchSubmit(event), onReset: () => this.resetSearchQuery() }, !!this.searchArea && (index.h("input", { key: '98862f739245597cd1c22b76c15e2e728a429f17', type: "hidden", name: "area", value: this.searchArea })), index.h("div", { key: '919e102ea248a41caea96fc3c7289b106d54195d', class: "input-wrapper", role: "none" }, this.searchQuery && (index.h("button", { key: 'd53357c9b63e6bae5b28809499265a7c332b5f2d', type: "reset", "aria-label": "Svuota campo di ricerca", disabled: !this.showSearchbar, "aria-hidden": !this.showSearchbar ? 'true' : undefined, tabIndex: !this.showSearchbar ? -1 : 0 }, index.h("z-icon", { key: '2ff06d5550f8701e6256f178b925153cac565be8', name: "multiply-circled" }))), index.h("input", { key: '879339821611ce65bd2777726ebabd0c44384b72', id: "searchbar-input", name: "q", type: "search", disabled: !this.showSearchbar, placeholder: "Cerca per parola chiave o ISBN", value: this.searchQuery, required: true, autocomplete: "off", role: "combobox", "aria-autocomplete": "list", "aria-expanded": this.suggestions.length ? 'true' : 'false', "aria-controls": "search-suggestions", "aria-activedescendant": this.activeSuggestion, "aria-label": "Cerca per parola chiave o ISBN", "aria-hidden": !this.showSearchbar ? 'true' : undefined, tabIndex: !this.showSearchbar ? -1 : 0, onInput: (event) => this.handleInputChange(event), onKeyDown: (e) => {
|
|
934
|
+
// INFO: prevent ESC from clearing input
|
|
935
|
+
if (isEscKey(e)) {
|
|
936
|
+
e.preventDefault();
|
|
937
|
+
}
|
|
938
|
+
this.handleSuggestionsNav(e);
|
|
939
|
+
} })), index.h("button", { key: '7101e9eedd9385bfeb5ee41a80d7e6842e75f493', class: "searchbar-button", "aria-label": this.showSearchbar ? 'Esegui ricerca' : 'Apri il campo di ricerca', "aria-controls": "searchbar-input", type: this.showSearchbar ? 'submit' : 'button', onClick: () => this.openSearchbar() }, this.showSearchbar ? null : index.h("span", { class: "searchbar-button-label" }, "Cerca"), index.h("z-icon", { key: '6e8d065e91e94fba49c64e856129d72155e88b84', name: "search" }))), this.renderSuggestions()));
|
|
698
940
|
}
|
|
699
941
|
static get watchers() { return {
|
|
700
|
-
"searchQuery": ["onSearchQueryChange"]
|
|
942
|
+
"searchQuery": ["onSearchQueryChange"],
|
|
943
|
+
"searchArea": ["onSearchAreaChange"],
|
|
944
|
+
"showSearchbar": ["onShowSearchbarChange"],
|
|
945
|
+
"showSuggestions": ["onShowSuggestionsChange"]
|
|
701
946
|
}; }
|
|
702
947
|
};
|
|
703
948
|
ZanitSearchForm.style = searchFormCss;
|