@zanichelli/zanichelli-it-frontend-kit 1.4.0-RC2 → 1.4.0-RC3

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.
Files changed (117) hide show
  1. package/dist/cjs/index-BLzQAHAI.js +1578 -0
  2. package/dist/cjs/index-BLzQAHAI.js.map +1 -0
  3. package/dist/cjs/index.cjs.js +5 -0
  4. package/dist/cjs/index.cjs.js.map +1 -0
  5. package/dist/cjs/loader.cjs.js +15 -0
  6. package/dist/cjs/loader.cjs.js.map +1 -0
  7. package/dist/cjs/zanichelli-it-frontend-kit.cjs.js +27 -0
  8. package/dist/cjs/zanichelli-it-frontend-kit.cjs.js.map +1 -0
  9. package/dist/cjs/zanit-back-to-top.zanit-menubar.zanit-mobile-menubar.zanit-search-form.entry.cjs.js.map +1 -0
  10. package/dist/cjs/zanit-back-to-top_4.cjs.entry.js +1024 -0
  11. package/dist/cjs/zanit-back-to-top_4.cjs.entry.js.map +1 -0
  12. package/dist/collection/collection-manifest.json +15 -0
  13. package/dist/collection/components/back-to-top/back-to-top.css +16 -0
  14. package/dist/collection/components/back-to-top/back-to-top.js +130 -0
  15. package/dist/collection/components/back-to-top/back-to-top.js.map +1 -0
  16. package/dist/collection/components/menubar/menu/menu.css +95 -0
  17. package/dist/collection/components/menubar/menu/menu.js +38 -0
  18. package/dist/collection/components/menubar/menu/menu.js.map +1 -0
  19. package/dist/collection/components/menubar/menubar.css +170 -0
  20. package/dist/{zanichelli-it-frontend-kit/zanit-menubar.entry.js → collection/components/menubar/menubar.js} +203 -25
  21. package/dist/collection/components/menubar/menubar.js.map +1 -0
  22. package/dist/collection/components/menubar/mobile-menubar/mobile-menubar.css +122 -0
  23. package/{www/build/zanit-mobile-menubar.entry.js → dist/collection/components/menubar/mobile-menubar/mobile-menubar.js} +194 -24
  24. package/dist/collection/components/menubar/mobile-menubar/mobile-menubar.js.map +1 -0
  25. package/dist/collection/components/menubar/search-form/search-form.css +232 -0
  26. package/dist/{zanichelli-it-frontend-kit/zanit-search-form.entry.js → collection/components/menubar/search-form/search-form.js} +174 -110
  27. package/dist/collection/components/menubar/search-form/search-form.js.map +1 -0
  28. package/dist/collection/components/menubar/search-form/suggestions.js +85 -0
  29. package/dist/collection/components/menubar/search-form/suggestions.js.map +1 -0
  30. package/dist/collection/index.js +11 -0
  31. package/dist/collection/index.js.map +1 -0
  32. package/dist/collection/utils/index.js +2 -0
  33. package/dist/collection/utils/index.js.map +1 -0
  34. package/dist/collection/utils/subjects.api.js +25 -0
  35. package/dist/collection/utils/subjects.api.js.map +1 -0
  36. package/dist/collection/utils/utils.js +25 -0
  37. package/dist/collection/utils/utils.js.map +1 -0
  38. package/dist/components/index.js +1335 -0
  39. package/dist/components/index.js.map +1 -0
  40. package/dist/{zanichelli-it-frontend-kit/zanit-mobile-menubar.entry.js → components/p-CmameXB-.js} +87 -12
  41. package/dist/components/p-CmameXB-.js.map +1 -0
  42. package/{www/build/zanit-search-form.entry.js → dist/components/p-DNk0AZSw.js} +92 -13
  43. package/dist/components/p-DNk0AZSw.js.map +1 -0
  44. package/dist/{zanichelli-it-frontend-kit/zanit-back-to-top.entry.js → components/zanit-back-to-top.js} +34 -10
  45. package/dist/components/zanit-back-to-top.js.map +1 -0
  46. package/{www/build/zanit-menubar.entry.js → dist/components/zanit-menubar.js} +57 -12
  47. package/dist/components/zanit-menubar.js.map +1 -0
  48. package/dist/components/zanit-mobile-menubar.js +9 -0
  49. package/dist/components/zanit-mobile-menubar.js.map +1 -0
  50. package/dist/components/zanit-search-form.js +9 -0
  51. package/dist/components/zanit-search-form.js.map +1 -0
  52. package/dist/esm/index-DSdvvVFj.js +1549 -0
  53. package/dist/esm/index-DSdvvVFj.js.map +1 -0
  54. package/dist/esm/index.js +4 -0
  55. package/dist/esm/index.js.map +1 -0
  56. package/dist/esm/loader.js +13 -0
  57. package/dist/esm/loader.js.map +1 -0
  58. package/dist/esm/zanichelli-it-frontend-kit.js +23 -0
  59. package/dist/esm/zanichelli-it-frontend-kit.js.map +1 -0
  60. package/dist/esm/zanit-back-to-top.zanit-menubar.zanit-mobile-menubar.zanit-search-form.entry.js.map +1 -0
  61. package/dist/esm/zanit-back-to-top_4.entry.js +1019 -0
  62. package/dist/esm/zanit-back-to-top_4.entry.js.map +1 -0
  63. package/dist/index.cjs.js +1 -0
  64. package/dist/index.js +1 -0
  65. package/dist/zanichelli-it-frontend-kit/index.esm.js +0 -10
  66. package/dist/zanichelli-it-frontend-kit/index.esm.js.map +1 -1
  67. package/dist/zanichelli-it-frontend-kit/p-0f6b9e37.entry.js +2 -0
  68. package/dist/zanichelli-it-frontend-kit/p-0f6b9e37.entry.js.map +1 -0
  69. package/dist/zanichelli-it-frontend-kit/p-DSdvvVFj.js +3 -0
  70. package/dist/zanichelli-it-frontend-kit/p-DSdvvVFj.js.map +1 -0
  71. package/dist/zanichelli-it-frontend-kit/zanichelli-it-frontend-kit.css +1 -993
  72. package/dist/zanichelli-it-frontend-kit/zanichelli-it-frontend-kit.esm.js +1 -49
  73. package/dist/zanichelli-it-frontend-kit/zanichelli-it-frontend-kit.esm.js.map +1 -1
  74. package/dist/zanichelli-it-frontend-kit/zanit-back-to-top.zanit-menubar.zanit-mobile-menubar.zanit-search-form.entry.esm.js.map +1 -0
  75. package/package.json +1 -1
  76. package/www/build/index.esm.js +0 -10
  77. package/www/build/index.esm.js.map +1 -1
  78. package/www/build/p-0f6b9e37.entry.js +2 -0
  79. package/www/build/p-0f6b9e37.entry.js.map +1 -0
  80. package/www/build/p-43c395dc.css +1 -0
  81. package/www/build/p-9134b2b7.js +2 -0
  82. package/www/build/p-DSdvvVFj.js +3 -0
  83. package/www/build/p-DSdvvVFj.js.map +1 -0
  84. package/www/build/zanichelli-it-frontend-kit.css +1 -993
  85. package/www/build/zanichelli-it-frontend-kit.esm.js +1 -49
  86. package/www/build/zanichelli-it-frontend-kit.esm.js.map +1 -1
  87. package/www/build/zanit-back-to-top.zanit-menubar.zanit-mobile-menubar.zanit-search-form.entry.esm.js.map +1 -0
  88. package/www/index.html +2 -11
  89. package/dist/zanichelli-it-frontend-kit/index-DPw_TAEB.js +0 -4170
  90. package/dist/zanichelli-it-frontend-kit/index-DPw_TAEB.js.map +0 -1
  91. package/dist/zanichelli-it-frontend-kit/menu-BsP3cOc_.js +0 -46
  92. package/dist/zanichelli-it-frontend-kit/menu-BsP3cOc_.js.map +0 -1
  93. package/dist/zanichelli-it-frontend-kit/subjects.api-BRhngFD0.js +0 -54
  94. package/dist/zanichelli-it-frontend-kit/subjects.api-BRhngFD0.js.map +0 -1
  95. package/dist/zanichelli-it-frontend-kit/zanit-back-to-top.entry.esm.js.map +0 -1
  96. package/dist/zanichelli-it-frontend-kit/zanit-back-to-top.entry.js.map +0 -1
  97. package/dist/zanichelli-it-frontend-kit/zanit-menubar.entry.esm.js.map +0 -1
  98. package/dist/zanichelli-it-frontend-kit/zanit-menubar.entry.js.map +0 -1
  99. package/dist/zanichelli-it-frontend-kit/zanit-mobile-menubar.entry.esm.js.map +0 -1
  100. package/dist/zanichelli-it-frontend-kit/zanit-mobile-menubar.entry.js.map +0 -1
  101. package/dist/zanichelli-it-frontend-kit/zanit-search-form.entry.esm.js.map +0 -1
  102. package/dist/zanichelli-it-frontend-kit/zanit-search-form.entry.js.map +0 -1
  103. package/www/build/index-DPw_TAEB.js +0 -4170
  104. package/www/build/index-DPw_TAEB.js.map +0 -1
  105. package/www/build/menu-BsP3cOc_.js +0 -46
  106. package/www/build/menu-BsP3cOc_.js.map +0 -1
  107. package/www/build/subjects.api-BRhngFD0.js +0 -54
  108. package/www/build/subjects.api-BRhngFD0.js.map +0 -1
  109. package/www/build/zanit-back-to-top.entry.esm.js.map +0 -1
  110. package/www/build/zanit-back-to-top.entry.js +0 -64
  111. package/www/build/zanit-back-to-top.entry.js.map +0 -1
  112. package/www/build/zanit-menubar.entry.esm.js.map +0 -1
  113. package/www/build/zanit-menubar.entry.js.map +0 -1
  114. package/www/build/zanit-mobile-menubar.entry.esm.js.map +0 -1
  115. package/www/build/zanit-mobile-menubar.entry.js.map +0 -1
  116. package/www/build/zanit-search-form.entry.esm.js.map +0 -1
  117. package/www/build/zanit-search-form.entry.js.map +0 -1
@@ -1,103 +1,12 @@
1
- import { r as registerInstance, e as createEvent, a as getElement, h, d as Host } from './index-DPw_TAEB.js';
2
- import { S as SearchEnv, g as getSubjectsByArea, c as containsTarget, i as isEscKey, a as isTabKey, b as isArrowDownKey, d as isArrowUpKey } from './subjects.api-BRhngFD0.js';
3
-
4
- var AREA_LABELS;
5
- (function (AREA_LABELS) {
6
- AREA_LABELS["SCUOLA"] = "Scuola";
7
- AREA_LABELS["UNIVERSIT\u00C0"] = "Universit\u00E0";
8
- AREA_LABELS["GIURIDICO"] = "Giuridico";
9
- AREA_LABELS["DIZIONARI"] = "Dizionari";
10
- AREA_LABELS["SAGGISTICA"] = "Saggistica";
11
- })(AREA_LABELS || (AREA_LABELS = {}));
12
- const AREA_ORDER = Object.keys(AREA_LABELS);
13
- function buildSuggestions(query, subjectsByArea, selectedArea) {
14
- const matchingSubjectAreas = findSubjectAreas(query, subjectsByArea);
15
- const hasSubject = matchingSubjectAreas.length > 0;
16
- const subject = hasSubject ? query.toUpperCase() : undefined;
17
- const suggestions = [];
18
- if (selectedArea)
19
- suggestions.push(buildWordSuggestion(query, selectedArea));
20
- suggestions.push(buildWordSuggestion(query));
21
- if (hasSubject) {
22
- if (selectedArea) {
23
- const orderedSubjectAreas = [
24
- ...matchingSubjectAreas.filter((area) => area === selectedArea),
25
- ...matchingSubjectAreas
26
- .filter((area) => area !== selectedArea)
27
- .sort((a, b) => getAreaOrder(a) - getAreaOrder(b)),
28
- ];
29
- orderedSubjectAreas.forEach((area) => suggestions.push(buildSubjectSuggestion(query, area, subject)));
30
- }
31
- else {
32
- matchingSubjectAreas
33
- .sort((a, b) => getAreaOrder(a) - getAreaOrder(b))
34
- .forEach((subjectArea) => suggestions.push(buildSubjectSuggestion(query, subjectArea, subject)));
35
- }
36
- }
37
- return suggestions;
38
- }
39
- const buildWordSuggestion = (user_query, area) => {
40
- return {
41
- id: buildId(`word-${user_query}-${area}`),
42
- label: buildLabel(user_query, area),
43
- aria_label: buildAriaLabel(user_query, area, false),
44
- url: buildUrl({ q: user_query, ...(area ? { area } : {}), user_query }),
45
- ...buildDetail(user_query, user_query, area),
46
- };
47
- };
48
- const buildSubjectSuggestion = (user_query, area, subject) => {
49
- return {
50
- id: buildId(`subj-${user_query}-${area}-${subject}`),
51
- label: buildLabel(user_query, area),
52
- aria_label: buildAriaLabel(user_query, area, true),
53
- url: buildUrl({ area, materia: subject, user_query }),
54
- ...buildDetail(user_query, undefined, area, subject),
55
- };
56
- };
57
- const buildId = (string) => string
58
- .split('')
59
- .map((c) => c.charCodeAt(0).toString(16))
60
- .join('');
61
- const buildUrl = (params) => {
62
- return `ricerca?${new URLSearchParams(params).toString()}`;
63
- };
64
- const buildDetail = (user_query, query, area, subject) => ({
65
- user_query,
66
- ...(query ? { query } : {}),
67
- ...(area ? { area } : {}),
68
- ...(subject ? { subject } : {}),
69
- });
70
- const buildLabel = (user_query, area) => {
71
- return `<mark>${user_query}</mark> in <strong>${area ? `${AREA_LABELS[area] ?? area}` : `tutto il sito`}</strong>`;
72
- };
73
- const buildAriaLabel = (user_query, area, isSubject = false) => {
74
- return `Cerca la ${isSubject ? `materia` : `parola`} ${user_query} ${area ? `nel catalogo ${AREA_LABELS[area] ?? area}` : `in tutto il sito`}`;
75
- };
76
- function findSubjectAreas(query, subjectsByArea) {
77
- const cleanedQuery = cleanSearch(query);
78
- return Object.entries(subjectsByArea)
79
- .filter(([, subjects]) => subjects.some((subject) => subject.toLowerCase() === cleanedQuery))
80
- .map(([area]) => area);
81
- }
82
- /** Clear search string: lowercase, remove multiple spaces */
83
- const cleanSearch = (s) => s.toLowerCase().replace(/\s+/g, ' ');
84
- const getAreaOrder = (area) => {
85
- const index = AREA_ORDER.indexOf(area);
86
- return index >= 0 ? index : 100;
87
- };
88
-
89
- 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);height:3rem;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;top:3rem;left:50%;width:100vw;border-top:1px solid var(--gray200);margin-left:-50vw;background:#fff;box-shadow:var(--shadow-1)}.suggestions-wrapper.hidden{display:none}.suggestions{display:flex;width:100%;flex-direction:column;align-items:stretch;padding:var(--space-unit);margin:0 auto}.suggestion-head{padding:calc(var(--space-unit) * 0.75) var(--space-unit);color:var(--gray700);font-size:0.875rem;font-weight:var(--font-md);line-height:1.125rem}.suggestion{display:flex;padding:calc(var(--space-unit) * 0.75) var(--space-unit);color:var(--gray900);cursor:pointer;font-size:1rem;gap:var(--space-unit);line-height:1.5rem}.suggestion:hover,.suggestion[aria-selected='true']{background:var(--gray100)}.suggestion strong{font-weight:var(--font-bd)}.suggestion mark{background-color:var(--red50)}.suggestion z-icon{--z-icon-height:1.125rem;margin-top:0.125rem}.suggestions z-divider{margin:var(--space-unit) 0}@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{max-width:1366px;padding:var(--space-unit) calc(var(--space-unit) * 3)}}";
90
-
91
- const ZanitSearchForm = class {
92
- constructor(hostRef) {
93
- registerInstance(this, hostRef);
94
- this.search = createEvent(this, "search", 7);
95
- this.resetSearch = createEvent(this, "resetSearch", 7);
96
- }
1
+ import { h, Host } from "@stencil/core";
2
+ import { containsTarget, isArrowDownKey, isArrowUpKey, isEscKey, isTabKey } from "../../../utils";
3
+ import { getSubjectsByArea, SearchEnv } from "../../../utils/subjects.api";
4
+ import { buildSuggestions } from "./suggestions";
5
+ export class ZanitSearchForm {
97
6
  formElement;
98
7
  subjectsByArea = {};
99
8
  timer;
100
- get host() { return getElement(this); }
9
+ host;
101
10
  /** Indicates whether the searchbar is visible and usable. */
102
11
  showSearchbar = false;
103
12
  /** Search query to apply. */
@@ -292,16 +201,171 @@ const ZanitSearchForm = class {
292
201
  this.handleSuggestionsNav(e);
293
202
  } })), h("button", { key: '4e0feaeaff7bcecaf6a29409a6accac895810fdf', 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 : h("span", { class: "searchbar-button-label" }, "Cerca"), h("z-icon", { key: '49eec7e6f04c34df57fcf99f405d1c3ada1fcdfb', name: "search" }))), this.renderSuggestions()));
294
203
  }
295
- static get watchers() { return {
296
- "searchQuery": ["onSearchQueryChange"],
297
- "searchArea": ["onSearchAreaChange"],
298
- "showSearchbar": ["onShowSearchbarChange"],
299
- "showSuggestions": ["onShowSuggestionsChange"]
300
- }; }
301
- };
302
- ZanitSearchForm.style = searchFormCss;
303
-
304
- export { ZanitSearchForm as zanit_search_form };
305
- //# sourceMappingURL=zanit-search-form.entry.esm.js.map
306
-
307
- //# sourceMappingURL=zanit-search-form.entry.js.map
204
+ static get is() { return "zanit-search-form"; }
205
+ static get encapsulation() { return "shadow"; }
206
+ static get originalStyleUrls() {
207
+ return {
208
+ "$": ["search-form.css"]
209
+ };
210
+ }
211
+ static get styleUrls() {
212
+ return {
213
+ "$": ["search-form.css"]
214
+ };
215
+ }
216
+ static get properties() {
217
+ return {
218
+ "searchQuery": {
219
+ "type": "string",
220
+ "attribute": "search-query",
221
+ "mutable": true,
222
+ "complexType": {
223
+ "original": "string | undefined",
224
+ "resolved": "string",
225
+ "references": {}
226
+ },
227
+ "required": false,
228
+ "optional": false,
229
+ "docs": {
230
+ "tags": [],
231
+ "text": "Initial search query"
232
+ },
233
+ "getter": false,
234
+ "setter": false,
235
+ "reflect": false,
236
+ "defaultValue": "undefined"
237
+ },
238
+ "searchEnv": {
239
+ "type": "string",
240
+ "attribute": "search-env",
241
+ "mutable": false,
242
+ "complexType": {
243
+ "original": "SearchEnv",
244
+ "resolved": "SearchEnv.DEV | SearchEnv.PROD | SearchEnv.TEST",
245
+ "references": {
246
+ "SearchEnv": {
247
+ "location": "import",
248
+ "path": "../../../utils/subjects.api",
249
+ "id": "src/utils/subjects.api.ts::SearchEnv"
250
+ }
251
+ }
252
+ },
253
+ "required": false,
254
+ "optional": false,
255
+ "docs": {
256
+ "tags": [],
257
+ "text": "Environment for search suggestions"
258
+ },
259
+ "getter": false,
260
+ "setter": false,
261
+ "reflect": false,
262
+ "defaultValue": "SearchEnv.PROD"
263
+ },
264
+ "searchArea": {
265
+ "type": "string",
266
+ "attribute": "search-area",
267
+ "mutable": false,
268
+ "complexType": {
269
+ "original": "string | undefined",
270
+ "resolved": "string",
271
+ "references": {}
272
+ },
273
+ "required": false,
274
+ "optional": true,
275
+ "docs": {
276
+ "tags": [],
277
+ "text": "Search area (e.g. \"SCUOLA\", \"UNIVERSIT\u00C0\", \"DIZIONARI\")."
278
+ },
279
+ "getter": false,
280
+ "setter": false,
281
+ "reflect": false
282
+ }
283
+ };
284
+ }
285
+ static get states() {
286
+ return {
287
+ "showSearchbar": {},
288
+ "_searchQuery": {},
289
+ "suggestions": {},
290
+ "activeSuggestion": {},
291
+ "showSuggestions": {}
292
+ };
293
+ }
294
+ static get events() {
295
+ return [{
296
+ "method": "search",
297
+ "name": "search",
298
+ "bubbles": true,
299
+ "cancelable": true,
300
+ "composed": true,
301
+ "docs": {
302
+ "tags": [],
303
+ "text": "Emitted on search form submission."
304
+ },
305
+ "complexType": {
306
+ "original": "SearchEvent",
307
+ "resolved": "{ query?: string; area?: string; subject?: string; user_query?: string; }",
308
+ "references": {
309
+ "SearchEvent": {
310
+ "location": "import",
311
+ "path": "../../../utils",
312
+ "id": "src/utils/index.ts::SearchEvent"
313
+ }
314
+ }
315
+ }
316
+ }, {
317
+ "method": "resetSearch",
318
+ "name": "resetSearch",
319
+ "bubbles": true,
320
+ "cancelable": true,
321
+ "composed": true,
322
+ "docs": {
323
+ "tags": [],
324
+ "text": ""
325
+ },
326
+ "complexType": {
327
+ "original": "void",
328
+ "resolved": "void",
329
+ "references": {}
330
+ }
331
+ }];
332
+ }
333
+ static get elementRef() { return "host"; }
334
+ static get watchers() {
335
+ return [{
336
+ "propName": "searchQuery",
337
+ "methodName": "onSearchQueryChange"
338
+ }, {
339
+ "propName": "searchArea",
340
+ "methodName": "onSearchAreaChange"
341
+ }, {
342
+ "propName": "showSearchbar",
343
+ "methodName": "onShowSearchbarChange"
344
+ }, {
345
+ "propName": "showSuggestions",
346
+ "methodName": "onShowSuggestionsChange"
347
+ }];
348
+ }
349
+ static get listeners() {
350
+ return [{
351
+ "name": "click",
352
+ "method": "handleOutsideClick",
353
+ "target": "document",
354
+ "capture": false,
355
+ "passive": true
356
+ }, {
357
+ "name": "keydown",
358
+ "method": "handleEsc",
359
+ "target": undefined,
360
+ "capture": false,
361
+ "passive": true
362
+ }, {
363
+ "name": "keyup",
364
+ "method": "handleTab",
365
+ "target": "document",
366
+ "capture": false,
367
+ "passive": true
368
+ }];
369
+ }
370
+ }
371
+ //# sourceMappingURL=search-form.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-form.js","sourceRoot":"","sources":["../../../../src/components/menubar/search-form/search-form.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Component, Element, Event, EventEmitter, h, Host, Listen, Prop, State, Watch } from '@stencil/core';\nimport { containsTarget, isArrowDownKey, isArrowUpKey, isEscKey, isTabKey, SearchEvent } from '../../../utils';\nimport { getSubjectsByArea, SearchEnv } from '../../../utils/subjects.api';\nimport { buildSuggestions, SearchSuggestion } from './suggestions';\n\n@Component({\n tag: 'zanit-search-form',\n styleUrl: 'search-form.css',\n shadow: true,\n})\nexport class ZanitSearchForm {\n private formElement: HTMLFormElement;\n private subjectsByArea: Record<string, string[]> = {};\n private timer: NodeJS.Timeout;\n\n @Element() host: HTMLZanitSearchFormElement;\n\n /** Indicates whether the searchbar is visible and usable. */\n @State()\n showSearchbar: boolean = false;\n\n /** Search query to apply. */\n @State()\n _searchQuery: string | undefined = undefined;\n\n /** Search suggestions to show in the autocomplete dropdown. */\n @State() suggestions: SearchSuggestion[] = [];\n\n /** Active suggestion - used for keyboard navigation */\n @State() activeSuggestion: string = '';\n\n /** Show suggestions list */\n @State() showSuggestions: boolean = false;\n\n /** Initial search query */\n @Prop({ mutable: true })\n searchQuery: string | undefined = undefined;\n\n /** Environment for search suggestions */\n @Prop() searchEnv: SearchEnv = SearchEnv.PROD;\n\n /** Search area (e.g. \"SCUOLA\", \"UNIVERSITÀ\", \"DIZIONARI\"). */\n @Prop() searchArea?: string | undefined;\n\n @Watch('searchQuery')\n onSearchQueryChange() {\n this._searchQuery = this.searchQuery;\n if (this.searchQuery) {\n this.openSearchbar();\n }\n this.resetSuggestions();\n }\n\n @Watch('searchArea')\n onSearchAreaChange() {\n this.resetSuggestions();\n }\n\n @Watch('showSearchbar')\n onShowSearchbarChange() {\n if (!this.showSearchbar) {\n this.showSuggestions = false;\n }\n }\n\n @Watch('showSuggestions')\n onShowSuggestionsChange() {\n this.activeSuggestion = '';\n }\n\n /** Emitted on search form submission. */\n @Event({ cancelable: true }) search: EventEmitter<SearchEvent>;\n\n @Event() resetSearch: EventEmitter<void>;\n\n async connectedCallback() {\n this.subjectsByArea = await getSubjectsByArea(this.searchEnv);\n this.showSearchbar = !!this.searchQuery;\n this._searchQuery = this.searchQuery;\n }\n\n /** Close open searchbar when clicking outside. */\n @Listen('click', { target: 'document', passive: true })\n handleOutsideClick(event: MouseEvent) {\n if (this.showSearchbar && this.host && !containsTarget(this.host, event)) {\n this.showSearchbar = false;\n }\n }\n\n /** Close the searchbar/suggestions when pressing Escape. */\n @Listen('keydown', { passive: true })\n handleEsc(event: KeyboardEvent) {\n if (!isEscKey(event)) {\n return;\n }\n\n if (this.showSuggestions) {\n this.showSuggestions = false;\n } else {\n this.showSearchbar = false;\n }\n }\n\n /** Close the searchbar/suggestions when pressing Tab. */\n @Listen('keyup', { target: 'document', passive: true })\n handleTab(event: KeyboardEvent) {\n if (!isTabKey(event)) {\n return;\n }\n\n this.showSuggestions = false;\n\n if (!containsTarget(this.host, event)) {\n this.showSearchbar = false;\n }\n }\n\n private openSearchbar() {\n this.showSearchbar = true;\n setTimeout(() => {\n const searchbarInput = this.host.shadowRoot.querySelector('#searchbar-input') as HTMLInputElement;\n searchbarInput.focus({ preventScroll: true });\n }, 500);\n }\n\n private resetSearchQuery() {\n this.searchQuery = undefined;\n this.resetSearch.emit();\n }\n\n private resetSuggestions() {\n this.suggestions = [];\n this.showSuggestions = false;\n }\n\n private handleInputChange(event: InputEvent) {\n this._searchQuery = (event.target as HTMLInputElement).value;\n if (!this._searchQuery) {\n this.searchQuery = undefined;\n }\n\n this.updateSuggestions();\n }\n\n private updateSuggestions() {\n clearTimeout(this.timer);\n\n const query = (this._searchQuery || '').trim();\n\n if (query.length < 3) {\n this.resetSuggestions();\n return;\n }\n\n this.timer = setTimeout(() => {\n this.resetSuggestions();\n this.suggestions = buildSuggestions(query, this.subjectsByArea, this.searchArea?.toUpperCase());\n this.showSuggestions = true;\n }, 300);\n }\n\n private onSearchSubmit(event: Event) {\n event.preventDefault();\n if (!this._searchQuery) {\n return;\n }\n\n if (this.activeSuggestion) {\n const suggestion = this.suggestions.find((s) => s.id === this.activeSuggestion);\n if (suggestion) {\n this.submitSuggestionSearch(suggestion);\n this.showSuggestions = false;\n return;\n }\n }\n\n this.showSearchbar = false;\n\n const searchEv = this.search.emit({ query: this._searchQuery, area: this.searchArea });\n // do not submit the form if the event default behavior was prevented\n if (searchEv.defaultPrevented) {\n return;\n }\n\n this.formElement.submit();\n }\n\n private submitSuggestionSearch(suggestion: SearchSuggestion) {\n const ev = this.search.emit({\n user_query: suggestion.user_query,\n query: suggestion.query,\n area: suggestion.area,\n subject: suggestion.subject,\n });\n if (!ev.defaultPrevented) {\n window.location.href = suggestion.url;\n }\n }\n\n private handleSuggestionsNav(event: KeyboardEvent) {\n if (!isArrowDownKey(event) && !isArrowUpKey(event)) {\n return;\n }\n\n if (!this.suggestions.length) {\n return;\n }\n\n const options = this.suggestions.map((o) => o.id);\n\n if (!options.length) {\n return;\n }\n\n event.preventDefault();\n event.stopPropagation();\n\n if (!this.showSuggestions) {\n this.showSuggestions = true;\n }\n\n let nextId = null;\n const firstId = options[0];\n const lastId = options[options.length - 1];\n const currOption = options.indexOf(this.activeSuggestion);\n if (currOption < 0) {\n nextId = isArrowDownKey(event) ? firstId : lastId;\n } else {\n if (isArrowDownKey(event)) {\n nextId = options[currOption + 1] || lastId;\n } else {\n nextId = options[currOption - 1] || firstId;\n }\n }\n this.activeSuggestion = nextId;\n }\n\n private renderSuggestions() {\n const renderHeading = (label: string, key: string) => (\n <span\n key={key}\n class=\"suggestion-head\"\n aria-hidden=\"true\"\n >\n {label}\n </span>\n );\n\n return (\n <div\n class={{ 'suggestions-wrapper': true, 'hidden': !this.showSuggestions || !this.suggestions.length }}\n onPointerOver={(e) => e.preventDefault()}\n >\n <div\n id=\"search-suggestions\"\n class=\"suggestions\"\n role=\"listbox\"\n aria-label=\"Seleziona tra i suggerimenti\"\n >\n {this.suggestions.map((suggestion, k) => {\n const items = [];\n\n if (k === 0) {\n items.push(renderHeading('Cerca la parola', 'word-head'));\n } else if (suggestion.subject && !this.suggestions[k - 1].subject) {\n items.push(<z-divider aria-hidden=\"true\" />);\n items.push(renderHeading('Cerca la materia', 'subj-head'));\n }\n\n items.push(\n <span\n key={k}\n id={suggestion.id}\n class=\"suggestion\"\n role=\"option\"\n aria-label={suggestion.aria_label}\n aria-selected={this.activeSuggestion === suggestion.id ? 'true' : undefined}\n onClick={() => this.submitSuggestionSearch(suggestion)}\n >\n <z-icon name=\"left-magnifying-glass\" />\n <span\n aria-hidden=\"true\"\n innerHTML={suggestion.label}\n />\n </span>\n );\n\n return items;\n })}\n </div>\n </div>\n );\n }\n\n render() {\n return (\n <Host>\n <form\n class={{ 'searchbar': true, 'searchbar-open': this.showSearchbar }}\n ref={(el) => (this.formElement = el)}\n role=\"search\"\n aria-label=\"Cerca nel sito\"\n method=\"get\"\n action=\"/ricerca\"\n onSubmit={(event) => this.onSearchSubmit(event)}\n onReset={() => this.resetSearchQuery()}\n >\n {!!this.searchArea && (\n <input\n type=\"hidden\"\n name=\"area\"\n value={this.searchArea}\n />\n )}\n\n <div\n class=\"input-wrapper\"\n role=\"none\"\n >\n {this.searchQuery && (\n <button\n type=\"reset\"\n aria-label=\"Svuota campo di ricerca\"\n disabled={!this.showSearchbar}\n aria-hidden={!this.showSearchbar ? 'true' : undefined}\n tabIndex={!this.showSearchbar ? -1 : 0}\n >\n <z-icon name=\"multiply-circled\" />\n </button>\n )}\n <input\n id=\"searchbar-input\"\n name=\"q\"\n type=\"search\"\n disabled={!this.showSearchbar}\n placeholder=\"Cerca per parola chiave o ISBN\"\n value={this.searchQuery}\n required\n autocomplete=\"off\"\n role=\"combobox\"\n aria-autocomplete=\"list\"\n aria-expanded={this.showSuggestions ? 'true' : 'false'}\n aria-controls=\"search-suggestions\"\n aria-activedescendant={this.activeSuggestion}\n aria-label=\"Cerca per parola chiave o ISBN\"\n aria-hidden={!this.showSearchbar ? 'true' : undefined}\n tabIndex={!this.showSearchbar ? -1 : 0}\n onInput={(event) => this.handleInputChange(event)}\n onKeyDown={(e) => {\n // INFO: prevent ESC from clearing input\n if (isEscKey(e)) {\n e.preventDefault();\n }\n\n this.handleSuggestionsNav(e);\n }}\n />\n </div>\n\n <button\n class=\"searchbar-button\"\n aria-label={this.showSearchbar ? 'Esegui ricerca' : 'Apri il campo di ricerca'}\n aria-controls=\"searchbar-input\"\n type={this.showSearchbar ? 'submit' : 'button'}\n onClick={() => this.openSearchbar()}\n >\n {this.showSearchbar ? null : <span class=\"searchbar-button-label\">Cerca</span>}\n <z-icon name=\"search\"></z-icon>\n </button>\n </form>\n\n {this.renderSuggestions()}\n </Host>\n );\n }\n}\n"]}
@@ -0,0 +1,85 @@
1
+ var AREA_LABELS;
2
+ (function (AREA_LABELS) {
3
+ AREA_LABELS["SCUOLA"] = "Scuola";
4
+ AREA_LABELS["UNIVERSIT\u00C0"] = "Universit\u00E0";
5
+ AREA_LABELS["GIURIDICO"] = "Giuridico";
6
+ AREA_LABELS["DIZIONARI"] = "Dizionari";
7
+ AREA_LABELS["SAGGISTICA"] = "Saggistica";
8
+ })(AREA_LABELS || (AREA_LABELS = {}));
9
+ const AREA_ORDER = Object.keys(AREA_LABELS);
10
+ export function buildSuggestions(query, subjectsByArea, selectedArea) {
11
+ const matchingSubjectAreas = findSubjectAreas(query, subjectsByArea);
12
+ const hasSubject = matchingSubjectAreas.length > 0;
13
+ const subject = hasSubject ? query.toUpperCase() : undefined;
14
+ const suggestions = [];
15
+ if (selectedArea)
16
+ suggestions.push(buildWordSuggestion(query, selectedArea));
17
+ suggestions.push(buildWordSuggestion(query));
18
+ if (hasSubject) {
19
+ if (selectedArea) {
20
+ const orderedSubjectAreas = [
21
+ ...matchingSubjectAreas.filter((area) => area === selectedArea),
22
+ ...matchingSubjectAreas
23
+ .filter((area) => area !== selectedArea)
24
+ .sort((a, b) => getAreaOrder(a) - getAreaOrder(b)),
25
+ ];
26
+ orderedSubjectAreas.forEach((area) => suggestions.push(buildSubjectSuggestion(query, area, subject)));
27
+ }
28
+ else {
29
+ matchingSubjectAreas
30
+ .sort((a, b) => getAreaOrder(a) - getAreaOrder(b))
31
+ .forEach((subjectArea) => suggestions.push(buildSubjectSuggestion(query, subjectArea, subject)));
32
+ }
33
+ }
34
+ return suggestions;
35
+ }
36
+ const buildWordSuggestion = (user_query, area) => {
37
+ return {
38
+ id: buildId(`word-${user_query}-${area}`),
39
+ label: buildLabel(user_query, area),
40
+ aria_label: buildAriaLabel(user_query, area, false),
41
+ url: buildUrl({ q: user_query, ...(area ? { area } : {}), user_query }),
42
+ ...buildDetail(user_query, user_query, area),
43
+ };
44
+ };
45
+ const buildSubjectSuggestion = (user_query, area, subject) => {
46
+ return {
47
+ id: buildId(`subj-${user_query}-${area}-${subject}`),
48
+ label: buildLabel(user_query, area),
49
+ aria_label: buildAriaLabel(user_query, area, true),
50
+ url: buildUrl({ area, materia: subject, user_query }),
51
+ ...buildDetail(user_query, undefined, area, subject),
52
+ };
53
+ };
54
+ const buildId = (string) => string
55
+ .split('')
56
+ .map((c) => c.charCodeAt(0).toString(16))
57
+ .join('');
58
+ const buildUrl = (params) => {
59
+ return `ricerca?${new URLSearchParams(params).toString()}`;
60
+ };
61
+ const buildDetail = (user_query, query, area, subject) => ({
62
+ user_query,
63
+ ...(query ? { query } : {}),
64
+ ...(area ? { area } : {}),
65
+ ...(subject ? { subject } : {}),
66
+ });
67
+ const buildLabel = (user_query, area) => {
68
+ return `<mark>${user_query}</mark> in <strong>${area ? `${AREA_LABELS[area] ?? area}` : `tutto il sito`}</strong>`;
69
+ };
70
+ const buildAriaLabel = (user_query, area, isSubject = false) => {
71
+ return `Cerca la ${isSubject ? `materia` : `parola`} ${user_query} ${area ? `nel catalogo ${AREA_LABELS[area] ?? area}` : `in tutto il sito`}`;
72
+ };
73
+ function findSubjectAreas(query, subjectsByArea) {
74
+ const cleanedQuery = cleanSearch(query);
75
+ return Object.entries(subjectsByArea)
76
+ .filter(([, subjects]) => subjects.some((subject) => subject.toLowerCase() === cleanedQuery))
77
+ .map(([area]) => area);
78
+ }
79
+ /** Clear search string: lowercase, remove multiple spaces */
80
+ const cleanSearch = (s) => s.toLowerCase().replace(/\s+/g, ' ');
81
+ const getAreaOrder = (area) => {
82
+ const index = AREA_ORDER.indexOf(area);
83
+ return index >= 0 ? index : 100;
84
+ };
85
+ //# sourceMappingURL=suggestions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"suggestions.js","sourceRoot":"","sources":["../../../../src/components/menubar/search-form/suggestions.ts"],"names":[],"mappings":"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","sourcesContent":["enum AREA_LABELS {\n SCUOLA = 'Scuola',\n UNIVERSITÀ = 'Università',\n GIURIDICO = 'Giuridico',\n DIZIONARI = 'Dizionari',\n SAGGISTICA = 'Saggistica',\n}\n\nconst AREA_ORDER = Object.keys(AREA_LABELS);\n\nexport type SearchSuggestion = {\n id: string;\n label: string;\n aria_label: string;\n url: string;\n user_query: string;\n query?: string;\n area?: string;\n subject?: string;\n};\n\nexport function buildSuggestions(\n query: string,\n subjectsByArea: Record<string, string[]>,\n selectedArea?: string\n): SearchSuggestion[] {\n const matchingSubjectAreas = findSubjectAreas(query, subjectsByArea);\n const hasSubject = matchingSubjectAreas.length > 0;\n const subject = hasSubject ? query.toUpperCase() : undefined;\n\n const suggestions: SearchSuggestion[] = [];\n\n if (selectedArea) suggestions.push(buildWordSuggestion(query, selectedArea));\n\n suggestions.push(buildWordSuggestion(query));\n\n if (hasSubject) {\n if (selectedArea) {\n const orderedSubjectAreas = [\n ...matchingSubjectAreas.filter((area) => area === selectedArea),\n ...matchingSubjectAreas\n .filter((area) => area !== selectedArea)\n .sort((a, b) => getAreaOrder(a) - getAreaOrder(b)),\n ];\n orderedSubjectAreas.forEach((area) => suggestions.push(buildSubjectSuggestion(query, area, subject)));\n } else {\n matchingSubjectAreas\n .sort((a, b) => getAreaOrder(a) - getAreaOrder(b))\n .forEach((subjectArea) => suggestions.push(buildSubjectSuggestion(query, subjectArea, subject)));\n }\n }\n\n return suggestions;\n}\n\nconst buildWordSuggestion = (user_query: string, area?: string): SearchSuggestion => {\n return {\n id: buildId(`word-${user_query}-${area}`),\n label: buildLabel(user_query, area),\n aria_label: buildAriaLabel(user_query, area, false),\n url: buildUrl({ q: user_query, ...(area ? { area } : {}), user_query }),\n ...buildDetail(user_query, user_query, area),\n };\n};\n\nconst buildSubjectSuggestion = (user_query: string, area: string, subject: string): SearchSuggestion => {\n return {\n id: buildId(`subj-${user_query}-${area}-${subject}`),\n label: buildLabel(user_query, area),\n aria_label: buildAriaLabel(user_query, area, true),\n url: buildUrl({ area, materia: subject, user_query }),\n ...buildDetail(user_query, undefined, area, subject),\n };\n};\n\nconst buildId = (string: string) =>\n string\n .split('')\n .map((c) => c.charCodeAt(0).toString(16))\n .join('');\n\nconst buildUrl = (params: Record<string, string>): string => {\n return `ricerca?${new URLSearchParams(params).toString()}`;\n};\n\nconst buildDetail = (user_query: string, query?: string, area?: string, subject?: string) => ({\n user_query,\n ...(query ? { query } : {}),\n ...(area ? { area } : {}),\n ...(subject ? { subject } : {}),\n});\n\nconst buildLabel = (user_query: string, area?: string) => {\n return `<mark>${user_query}</mark> in <strong>${area ? `${AREA_LABELS[area] ?? area}` : `tutto il sito`}</strong>`;\n};\n\nconst buildAriaLabel = (user_query: string, area?: string, isSubject: boolean = false) => {\n return `Cerca la ${isSubject ? `materia` : `parola`} ${user_query} ${area ? `nel catalogo ${AREA_LABELS[area] ?? area}` : `in tutto il sito`}`;\n};\n\nfunction findSubjectAreas(query: string, subjectsByArea: Record<string, string[]>): string[] {\n const cleanedQuery = cleanSearch(query);\n return Object.entries(subjectsByArea)\n .filter(([, subjects]) => subjects.some((subject) => subject.toLowerCase() === cleanedQuery))\n .map(([area]) => area);\n}\n\n/** Clear search string: lowercase, remove multiple spaces */\nconst cleanSearch = (s: string) => s.toLowerCase().replace(/\\s+/g, ' ');\n\nconst getAreaOrder = (area: string) => {\n const index = AREA_ORDER.indexOf(area);\n return index >= 0 ? index : 100;\n};\n"]}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * @fileoverview entry point for your component library
3
+ *
4
+ * This is the entry point for your component library. Use this file to export utilities,
5
+ * constants or data structure that accompany your components.
6
+ *
7
+ * DO NOT use this file to export your components. Instead, use the recommended approaches
8
+ * to consume components of this package as outlined in the `README.md`.
9
+ */
10
+ export * from './utils/types';
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,cAAc,eAAe,CAAC","sourcesContent":["/**\n * @fileoverview entry point for your component library\n *\n * This is the entry point for your component library. Use this file to export utilities,\n * constants or data structure that accompany your components.\n *\n * DO NOT use this file to export your components. Instead, use the recommended approaches\n * to consume components of this package as outlined in the `README.md`.\n */\n\nexport type * from './components.d.ts';\nexport * from './utils/types';\n"]}
@@ -0,0 +1,2 @@
1
+ export * from './utils';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC","sourcesContent":["export * from './utils';\n\nexport type * from './types';\n"]}
@@ -0,0 +1,25 @@
1
+ export var SearchEnv;
2
+ (function (SearchEnv) {
3
+ SearchEnv["DEV"] = "dev";
4
+ SearchEnv["TEST"] = "test";
5
+ SearchEnv["PROD"] = "prod";
6
+ })(SearchEnv || (SearchEnv = {}));
7
+ const S3_SHOP_URL = {
8
+ dev: 'https://zanichelli-shop-dev.s3.eu-west-1.amazonaws.com',
9
+ test: 'https://zanichelli-shop-test.s3.eu-west-1.amazonaws.com',
10
+ prod: 'https://zanichelli-shop.s3.eu-west-1.amazonaws.com',
11
+ };
12
+ export async function getSubjectsByArea(searchEnv) {
13
+ try {
14
+ const response = await fetch(`${S3_SHOP_URL[searchEnv]}/categories.json`);
15
+ if (!response.ok) {
16
+ throw new Error(`HTTP ${response.status}`);
17
+ }
18
+ return await response.json();
19
+ }
20
+ catch (err) {
21
+ console.error('Error fetching subjects:', err);
22
+ return {};
23
+ }
24
+ }
25
+ //# sourceMappingURL=subjects.api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subjects.api.js","sourceRoot":"","sources":["../../src/utils/subjects.api.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,SAIX;AAJD,WAAY,SAAS;IACnB,wBAAW,CAAA;IACX,0BAAa,CAAA;IACb,0BAAa,CAAA;AACf,CAAC,EAJW,SAAS,KAAT,SAAS,QAIpB;AAED,MAAM,WAAW,GAA2B;IAC1C,GAAG,EAAE,wDAAwD;IAC7D,IAAI,EAAE,yDAAyD;IAC/D,IAAI,EAAE,oDAAoD;CAC3D,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,SAAoB;IAC1D,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,WAAW,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;QAC1E,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,QAAQ,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;QAC7C,CAAC;QACD,OAAO,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IAC/B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,0BAA0B,EAAE,GAAG,CAAC,CAAC;QAC/C,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC","sourcesContent":["export enum SearchEnv {\n DEV = 'dev',\n TEST = 'test',\n PROD = 'prod',\n}\n\nconst S3_SHOP_URL: Record<string, string> = {\n dev: 'https://zanichelli-shop-dev.s3.eu-west-1.amazonaws.com',\n test: 'https://zanichelli-shop-test.s3.eu-west-1.amazonaws.com',\n prod: 'https://zanichelli-shop.s3.eu-west-1.amazonaws.com',\n};\n\nexport async function getSubjectsByArea(searchEnv: SearchEnv): Promise<Record<string, string[]>> {\n try {\n const response = await fetch(`${S3_SHOP_URL[searchEnv]}/categories.json`);\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}`);\n }\n return await response.json();\n } catch (err) {\n console.error('Error fetching subjects:', err);\n return {};\n }\n}\n"]}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Check if an element contains an event target by checking its composedPath.
3
+ * Useful when an event target may come from a component's shadow DOM.
4
+ */
5
+ export const containsTarget = (ancestor, event) => {
6
+ return event
7
+ .composedPath()
8
+ .filter((el) => el !== document && el !== window.window)
9
+ .some((el) => ancestor.contains(el));
10
+ };
11
+ /** Move the focus to `next` element, set tabindex to 0 for `next` and -1 to `current`. */
12
+ export const moveFocus = (current, next) => {
13
+ current.tabIndex = -1;
14
+ next.tabIndex = 0;
15
+ next.focus({ preventScroll: true });
16
+ };
17
+ /** Check if event key is ArrowUp */
18
+ export const isArrowUpKey = (event) => event.key === 'ArrowUp';
19
+ /** Check if event key is ArrowDown */
20
+ export const isArrowDownKey = (event) => event.key === 'ArrowDown';
21
+ /** Check if event key is Tab */
22
+ export const isTabKey = (event) => event.key === 'Tab';
23
+ /** Check if event key is Escape */
24
+ export const isEscKey = (event) => event.key === 'Escape';
25
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils/utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,QAAqB,EAAE,KAAY,EAAE,EAAE;IACpE,OAAO,KAAK;SACT,YAAY,EAAE;SACd,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,KAAK,QAAQ,IAAI,EAAE,KAAK,MAAM,CAAC,MAAM,CAAC;SACvD,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAiB,CAAC,CAAC,CAAC;AACxD,CAAC,CAAC;AAEF,0FAA0F;AAC1F,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,OAAoB,EAAE,IAAiB,EAAE,EAAE;IACnE,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC;IACtB,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC;IAClB,IAAI,CAAC,KAAK,CAAC,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;AACtC,CAAC,CAAC;AAEF,oCAAoC;AACpC,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,KAAoB,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,KAAK,SAAS,CAAC;AAE9E,sCAAsC;AACtC,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,KAAoB,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,KAAK,WAAW,CAAC;AAElF,gCAAgC;AAChC,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,KAAoB,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,KAAK,KAAK,CAAC;AAEtE,mCAAmC;AACnC,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,KAAoB,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,KAAK,QAAQ,CAAC","sourcesContent":["/**\n * Check if an element contains an event target by checking its composedPath.\n * Useful when an event target may come from a component's shadow DOM.\n */\nexport const containsTarget = (ancestor: HTMLElement, event: Event) => {\n return event\n .composedPath()\n .filter((el) => el !== document && el !== window.window)\n .some((el) => ancestor.contains(el as HTMLElement));\n};\n\n/** Move the focus to `next` element, set tabindex to 0 for `next` and -1 to `current`. */\nexport const moveFocus = (current: HTMLElement, next: HTMLElement) => {\n current.tabIndex = -1;\n next.tabIndex = 0;\n next.focus({ preventScroll: true });\n};\n\n/** Check if event key is ArrowUp */\nexport const isArrowUpKey = (event: KeyboardEvent) => event.key === 'ArrowUp';\n\n/** Check if event key is ArrowDown */\nexport const isArrowDownKey = (event: KeyboardEvent) => event.key === 'ArrowDown';\n\n/** Check if event key is Tab */\nexport const isTabKey = (event: KeyboardEvent) => event.key === 'Tab';\n\n/** Check if event key is Escape */\nexport const isEscKey = (event: KeyboardEvent) => event.key === 'Escape';\n"]}