mypgs 1.3.2 → 1.3.3

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 (73) hide show
  1. package/AI_GUIDELINES.md +353 -0
  2. package/README.md +483 -53
  3. package/assets/javascript/_imports.js +12 -11
  4. package/assets/javascript/_pgs.js +16 -1
  5. package/assets/javascript/components/_accordion.js +18 -9
  6. package/assets/javascript/components/_dropdown.js +176 -120
  7. package/assets/javascript/components/_menu.js +15 -116
  8. package/assets/javascript/components/_modals.js +0 -1
  9. package/assets/javascript/components/_notifications.js +2 -3
  10. package/assets/javascript/components/_slides.js +0 -1
  11. package/assets/javascript/components/_stepTabs.js +0 -1
  12. package/assets/javascript/components/_steps.js +0 -1
  13. package/assets/javascript/patterns/_cookieConsent.js +8 -2
  14. package/assets/javascript/pgs.d.ts +12 -1
  15. package/assets/scss/base/_html.scss +23 -1
  16. package/assets/scss/components/_dropdown.scss +24 -88
  17. package/assets/scss/components/_menu.scss +129 -15
  18. package/assets/scss/components/_modals.scss +15 -3
  19. package/assets/scss/components/_notification.scss +11 -14
  20. package/assets/scss/components/_tooltip.scss +2 -9
  21. package/assets/scss/index.scss +0 -1
  22. package/assets/scss/layout/_gap.scss +7 -1
  23. package/assets/scss/layout/_layout.scss +0 -12
  24. package/assets/scss/layout/_pageShell.scss +104 -105
  25. package/assets/scss/mixin/_mx-form.scss +1 -3
  26. package/assets/scss/mixin/_mx-responsive.scss +2 -2
  27. package/assets/scss/mixin/_mx-semantic.scss +0 -60
  28. package/assets/scss/mixin/mixin.scss +0 -1
  29. package/assets/scss/patterns/_footer.scss +1 -0
  30. package/assets/scss/patterns/_header.scss +20 -18
  31. package/dist/css/index.css +324 -1160
  32. package/dist/css/index.css.map +1 -1
  33. package/dist/css/index.min.css +1 -1
  34. package/dist/index.d.ts +12 -1
  35. package/dist/javascript/index.js +277 -272
  36. package/dist/javascript/index.js.map +1 -1
  37. package/dist/javascript/index.min.js +1 -1
  38. package/package.json +1 -1
  39. package/templates/components/{md-accordion.html → accordion.html} +2 -2
  40. package/templates/components/dropdown.html +91 -0
  41. package/templates/components/menu.html +41 -0
  42. package/templates/components/modal.html +78 -0
  43. package/templates/components/notification.html +35 -0
  44. package/templates/components/{md-slides.html → slides.html} +5 -5
  45. package/templates/components/{md-steps.html → steps.html} +7 -7
  46. package/templates/components/{md-tooltip.html → tooltip.html} +4 -2
  47. package/templates/demo.css +18 -0
  48. package/templates/demo.html +4 -5
  49. package/templates/demo.js +53 -52
  50. package/templates/layout/flex.html +89 -0
  51. package/templates/layout/grid.html +89 -0
  52. package/templates/layout/pageShell.html +59 -0
  53. package/templates/layout/section.html +40 -0
  54. package/templates/{layout/md-footer.html → patterns/footer.html} +1 -0
  55. package/templates/{layout/md-header.html → patterns/header.html} +6 -9
  56. package/assets/scss/base/_reset.scss +0 -15
  57. package/assets/scss/mixin/_mx-menu.scss +0 -154
  58. package/templates/components/md-dropdown.html +0 -16
  59. package/templates/components/md-menu.html +0 -40
  60. package/templates/components/md-modal.html +0 -19
  61. package/templates/components/md-notification.html +0 -13
  62. package/templates/layout/md-pageShell.html +0 -22
  63. package/templates/layout/md-section.html +0 -25
  64. /package/templates/components/{md-breadcumbs.html → breadcumbs.html} +0 -0
  65. /package/templates/components/{md-button.html → button.html} +0 -0
  66. /package/templates/components/{md-card.html → card.html} +0 -0
  67. /package/templates/components/{md-form.html → form.html} +0 -0
  68. /package/templates/components/{md-logo.html → logo.html} +0 -0
  69. /package/templates/components/{md-searchbar.html → searchbar.html} +0 -0
  70. /package/templates/components/{md-stepTabs.html → stepTabs.html} +0 -0
  71. /package/templates/components/{md-table.html → table.html} +0 -0
  72. /package/templates/layout/{md-body.html → body.html} +0 -0
  73. /package/templates/{layout/md-cookieConsent.html → patterns/cookieConsent.html} +0 -0
@@ -33,19 +33,33 @@ __webpack_require__.r(__webpack_exports__);
33
33
 
34
34
 
35
35
 
36
- _pgs_js__WEBPACK_IMPORTED_MODULE_0__.pgs.registerImport({
37
- PGS_accordion: _components_accordion_js__WEBPACK_IMPORTED_MODULE_1__.PGS_accordion,
38
- PGS_dropdown: _components_dropdown_js__WEBPACK_IMPORTED_MODULE_2__.PGS_dropdown,
39
- PGS_menu: _components_menu_js__WEBPACK_IMPORTED_MODULE_3__.PGS_menu,
40
- PGS_modal: _components_modals_js__WEBPACK_IMPORTED_MODULE_4__.PGS_modal,
41
- PGS_notification: _components_notifications_js__WEBPACK_IMPORTED_MODULE_5__.PGS_notification,
42
- PGS_slides: _components_slides_js__WEBPACK_IMPORTED_MODULE_6__.PGS_slides,
43
- PGS_stepTabs: _components_stepTabs_js__WEBPACK_IMPORTED_MODULE_7__.PGS_stepTabs,
44
- PGS_steps: _components_steps_js__WEBPACK_IMPORTED_MODULE_8__.PGS_steps,
45
- PGS_formValidate: _functions_formValidate_js__WEBPACK_IMPORTED_MODULE_9__.PGS_formValidate,
46
- PGS_scrollHorizontal: _functions_scrollY_js__WEBPACK_IMPORTED_MODULE_10__.PGS_scrollHorizontal,
36
+ _pgs_js__WEBPACK_IMPORTED_MODULE_0__.pgs.registerModules({
37
+ accordion: _components_accordion_js__WEBPACK_IMPORTED_MODULE_1__.PGS_accordion,
38
+ dropdown: _components_dropdown_js__WEBPACK_IMPORTED_MODULE_2__.PGS_dropdown,
39
+ menu: _components_menu_js__WEBPACK_IMPORTED_MODULE_3__.PGS_menu,
40
+ modal: _components_modals_js__WEBPACK_IMPORTED_MODULE_4__.PGS_modal,
41
+ notification: _components_notifications_js__WEBPACK_IMPORTED_MODULE_5__.PGS_notification,
42
+ slides: _components_slides_js__WEBPACK_IMPORTED_MODULE_6__.PGS_slides,
43
+ stepTabs: _components_stepTabs_js__WEBPACK_IMPORTED_MODULE_7__.PGS_stepTabs,
44
+ steps: _components_steps_js__WEBPACK_IMPORTED_MODULE_8__.PGS_steps,
45
+ formValidate: _functions_formValidate_js__WEBPACK_IMPORTED_MODULE_9__.PGS_formValidate,
46
+ scrollHorizontal: _functions_scrollY_js__WEBPACK_IMPORTED_MODULE_10__.PGS_scrollHorizontal,
47
47
  });
48
48
 
49
+ // pgs.registerImport({
50
+ // PGS_accordion,
51
+ // PGS_dropdown,
52
+ // PGS_menu,
53
+ // PGS_modal,
54
+ // PGS_notification,
55
+ // PGS_slides,
56
+ // PGS_stepTabs,
57
+ // PGS_steps,
58
+ // PGS_formValidate,
59
+ // PGS_scrollHorizontal,
60
+ // });
61
+
62
+
49
63
 
50
64
  /***/ },
51
65
 
@@ -282,7 +296,6 @@ function pgs(root) {
282
296
  const api = createBasePgs();
283
297
  api.state = createState("pgs-state");
284
298
  api.option = createOption("pgs-option");
285
- api.modules = createOption("pgs-modules");
286
299
  return api;
287
300
  }
288
301
 
@@ -312,6 +325,22 @@ pgs.registerImport = function (...modules) {
312
325
  return pgs;
313
326
  };
314
327
 
328
+ pgs.registerModules = function (modules = {}) {
329
+ Object.entries(modules).forEach(([name, module]) => {
330
+ const key = String(name || "").trim();
331
+ if (!key) return;
332
+
333
+ const hasOwn = Object.prototype.hasOwnProperty.call(pgs, key);
334
+ if (hasOwn && pgs[key] !== module) {
335
+ throw new Error(`pgs.registerModules(): "${key}" e' gia' definito su pgs`);
336
+ }
337
+
338
+ pgs[key] = module;
339
+ });
340
+
341
+ return pgs;
342
+ };
343
+
315
344
  pgs.import = function (...names) {
316
345
  return names.flat().reduce((imports, name) => {
317
346
  const key = String(name || "").trim().replace(/^pgs[_-\s]*/i, "").toLowerCase();
@@ -527,17 +556,27 @@ __webpack_require__.r(__webpack_exports__);
527
556
  /* harmony export */ });
528
557
  //= ACCORDION
529
558
  const API = new WeakMap();
559
+ let accordionId = 0;
560
+
561
+ function nextAccordionId() {
562
+ accordionId += 1;
563
+ return accordionId;
564
+ }
565
+
566
+ function directPgsChild(element, token) {
567
+ return Array.from(element.children).find(child => pgs(child).contains(token));
568
+ }
530
569
 
531
570
  function PGS_accordion_init(root = document) {
532
- pgs(root).querySelectorAll("accordion").forEach((accordion, index) => {
571
+ pgs(root).querySelectorAll("accordion").forEach((accordion) => {
533
572
  if (API.has(accordion)) return;
534
573
 
535
- const BUTTON = pgs(accordion).querySelector("accordion-button");
536
- const CONTENT = pgs(accordion).querySelector("accordion-content");
574
+ const BUTTON = directPgsChild(accordion, "accordion-button");
575
+ const CONTENT = directPgsChild(accordion, "accordion-content");
537
576
  if (!BUTTON || !CONTENT) return;
538
577
 
539
578
  //== ID univoci per aria-controls / aria-labelledby
540
- const ID = index + 1;
579
+ const ID = nextAccordionId();
541
580
  const btnId = `acc-btn-${ID}`;
542
581
  const panelId = `acc-panel-${ID}`;
543
582
 
@@ -547,12 +586,12 @@ function PGS_accordion_init(root = document) {
547
586
  //== Accessibilità (setup una volta)
548
587
  BUTTON.setAttribute("role", "button");
549
588
  BUTTON.setAttribute("tabindex", "0");
550
- BUTTON.setAttribute("id", btnId);
551
- BUTTON.setAttribute("aria-controls", panelId);
589
+ if (!BUTTON.id) BUTTON.setAttribute("id", btnId);
552
590
 
553
- CONTENT.setAttribute("id", panelId);
591
+ if (!CONTENT.id) CONTENT.setAttribute("id", panelId);
592
+ BUTTON.setAttribute("aria-controls", CONTENT.id);
554
593
  CONTENT.setAttribute("role", "region");
555
- CONTENT.setAttribute("aria-labelledby", btnId);
594
+ CONTENT.setAttribute("aria-labelledby", BUTTON.id);
556
595
 
557
596
  //+ Accessibility (applica stato aperto/chiuso)
558
597
  function accordionAccessibility(isOpen, button, content) {
@@ -637,7 +676,6 @@ function PGS_accordion_api(selector) {
637
676
  }
638
677
 
639
678
  const PGS_accordion = {
640
- PGS_name: "PGS_accordion",
641
679
  init: PGS_accordion_init,
642
680
  api: PGS_accordion_api
643
681
  };
@@ -654,150 +692,205 @@ const PGS_accordion = {
654
692
  "use strict";
655
693
  __webpack_require__.r(__webpack_exports__);
656
694
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
657
- /* harmony export */ PGS_dropdown: () => (/* binding */ PGS_dropdown),
658
- /* harmony export */ PGS_dropdown_api: () => (/* binding */ PGS_dropdown_api),
659
- /* harmony export */ PGS_dropdown_init: () => (/* binding */ PGS_dropdown_init)
695
+ /* harmony export */ PGS_dropdown: () => (/* binding */ PGS_dropdown)
660
696
  /* harmony export */ });
661
- // + dropdown (Popover API)
697
+ // + dropdown
662
698
  const API = new WeakMap();
699
+ const OPEN_DROPDOWNS = new Set();
700
+ const VIEWPORT_GAP = 8;
701
+ let dropdownId = 0;
663
702
 
664
- function PGS_dropdown_init(root = document) {
665
- pgs(root).querySelectorAll("dropdown").forEach((DROPDOWN, index) => {
666
- if (API.has(DROPDOWN)) return;
703
+ function nextDropdownId() {
704
+ dropdownId += 1;
705
+ return dropdownId;
706
+ }
667
707
 
668
- const BUTTON = pgs(DROPDOWN).querySelector("dropdown-button");
669
- const CONTENT = pgs(DROPDOWN).querySelector("dropdown-content");
708
+ function isDropdownContent(element) {
709
+ return element instanceof Element && pgs(element).contains("dropdown-content");
710
+ }
670
711
 
671
- if (!BUTTON || !CONTENT) return;
712
+ function getDropdownTrigger(dropdown, content) {
713
+ const children = Array.from(dropdown.children).filter(child => child !== content);
714
+ const dropdownButton = children.find(child => pgs(child).contains("dropdown-button"));
672
715
 
673
- // = INIT
674
- if (DROPDOWN.getAttribute("data-initialize") === "true") return;
675
- DROPDOWN.setAttribute("data-initialize", "true");
716
+ return dropdownButton || children.find(child => !isDropdownContent(child)) || dropdown;
717
+ }
676
718
 
677
- // == CSS dropdown-anchor
678
- const ANCHOR_NAME = `--dropdown-anchor-${index}`;
679
- DROPDOWN.style.setProperty("--dropdown-anchor", ANCHOR_NAME);
719
+ function getDropdownContent(dropdown) {
720
+ return Array.from(dropdown.children).find(isDropdownContent) || pgs(dropdown).querySelector("dropdown-content");
721
+ }
680
722
 
681
- // == IDs + ACCESSIBILITY
682
- if (!BUTTON.id) BUTTON.id = `dropdown-btn-${index}`;
683
- if (!CONTENT.id) CONTENT.id = `dropdown-panel-${index}`;
684
- BUTTON.setAttribute("type", "button");
685
- BUTTON.setAttribute("aria-haspopup", "true");
686
- BUTTON.setAttribute("aria-controls", CONTENT.id);
687
- BUTTON.setAttribute("aria-expanded", "false");
688
- CONTENT.setAttribute("aria-labelledby", BUTTON.id);
723
+ function getDropdowns(root) {
724
+ const dropdowns = root instanceof Element && pgs(root).contains("dropdown") ? [root] : [];
725
+ dropdowns.push(...pgs(root).querySelectorAll("dropdown"));
726
+ return dropdowns;
727
+ }
689
728
 
690
- // == POPVER SETUP
691
- if (!CONTENT.hasAttribute("popover")) CONTENT.setAttribute("popover", "auto");
692
- BUTTON.setAttribute("popovertarget", CONTENT.id);
693
- BUTTON.setAttribute("popovertargetaction", "toggle");
694
-
695
- //-( Safari / legacy fallback: popover is in the top layer, so fixed coords are viewport-based.
696
- const HAS_ANCHOR_POSITIONING =
697
- CSS.supports("anchor-name: --dropdown-anchor") &&
698
- CSS.supports("position-anchor: --dropdown-anchor") &&
699
- CSS.supports("position-area: bottom") &&
700
- CSS.supports("top: anchor(bottom)");
701
- const USE_FALLBACK_POSITIONING = pgs(DROPDOWN).contains("tooltip") || !HAS_ANCHOR_POSITIONING;
702
-
703
- const updatePopoverPosition = () => {
704
- if (!USE_FALLBACK_POSITIONING) return;
705
-
706
- const buttonRect = BUTTON.getBoundingClientRect();
707
- const style = getComputedStyle(DROPDOWN);
708
- const offset = parseFloat(style.getPropertyValue("--dropdown-offset")) || 10;
709
- const padding = parseFloat(style.getPropertyValue("--dropdown-padding")) || 0;
710
- const arrowSize = parseFloat(style.getPropertyValue("--dropdown-arrow-size")) || 12;
711
- const viewportGap = 8;
712
- const viewportWidth = window.innerWidth;
713
- const maxWidth = viewportWidth - viewportGap * 2;
714
- const contentStyle = getComputedStyle(CONTENT);
715
- const cssMaxWidth = parseFloat(contentStyle.maxWidth);
716
- const dropdownMaxWidth = Number.isFinite(cssMaxWidth) ? Math.min(cssMaxWidth, maxWidth) : maxWidth;
717
- const contentWidth = Math.min(
718
- Math.max(CONTENT.scrollWidth + padding * 2, buttonRect.width),
719
- dropdownMaxWidth
720
- );
721
- const top = buttonRect.bottom + offset;
722
- const centeredLeft = buttonRect.left + buttonRect.width / 2 - contentWidth / 2;
723
- const left = Math.min(
724
- Math.max(centeredLeft, viewportGap),
725
- viewportWidth - contentWidth - viewportGap
726
- );
727
- const buttonCenter = buttonRect.left + buttonRect.width / 2;
728
- const arrowLeft = Math.min(
729
- Math.max(buttonCenter - left, padding + arrowSize),
730
- contentWidth - padding - arrowSize
731
- );
729
+ function getposition(dropdown) {
730
+ const option = pgs(dropdown).option;
731
+ const optionValue = option.getValueBrackets("position");
732
+ const raw = (optionValue || "bottom center").trim().toLowerCase();
733
+ const parts = raw.split(/\s+/).filter(Boolean);
734
+ const side = parts.find(part => ["top", "right", "bottom", "left"].includes(part)) || "bottom";
735
+ const align = parts.find(part => ["top", "right", "bottom", "left", "center"].includes(part) && part !== side) || "center";
732
736
 
733
- DROPDOWN.style.setProperty("--dropdown-fallback-top", `${top}px`);
734
- DROPDOWN.style.setProperty("--dropdown-fallback-left", `${left}px`);
735
- DROPDOWN.style.setProperty("--dropdown-arrow-left", `${arrowLeft}px`);
736
- };
737
+ return { side, align };
738
+ }
737
739
 
738
- BUTTON.addEventListener("click", e => {
739
- if (!USE_FALLBACK_POSITIONING) return;
740
+ function clamp(value, min, max) {
741
+ return Math.min(Math.max(value, min), max);
742
+ }
740
743
 
741
- e.preventDefault();
742
- if (CONTENT.matches(":popover-open")) {
743
- CONTENT.hidePopover();
744
- return;
745
- }
744
+ function updateposition(dropdown) {
745
+ const data = API.get(dropdown);
746
+ if (!data || !data.isOpen()) return;
747
+
748
+ const { trigger, content } = data;
749
+ const { side, align } = getposition(dropdown);
750
+ const triggerRect = trigger.getBoundingClientRect();
751
+ const contentRect = content.getBoundingClientRect();
752
+ const viewportWidth = document.documentElement.clientWidth;
753
+ const maxLeft = Math.max(VIEWPORT_GAP, viewportWidth - contentRect.width - VIEWPORT_GAP);
754
+ let left = triggerRect.left + (triggerRect.width - contentRect.width) / 2;
755
+ let top = triggerRect.bottom + VIEWPORT_GAP;
756
+
757
+ if (side === "top" || side === "bottom") {
758
+ top = side === "top"
759
+ ? triggerRect.top - contentRect.height - VIEWPORT_GAP
760
+ : triggerRect.bottom + VIEWPORT_GAP;
761
+
762
+ if (align === "left") left = triggerRect.left;
763
+ if (align === "right") left = triggerRect.right - contentRect.width;
764
+ }
746
765
 
747
- updatePopoverPosition();
748
- CONTENT.showPopover();
749
- });
766
+ if (side === "left" || side === "right") {
767
+ left = side === "left"
768
+ ? triggerRect.left - contentRect.width - VIEWPORT_GAP
769
+ : triggerRect.right + VIEWPORT_GAP;
770
+ top = triggerRect.top + (triggerRect.height - contentRect.height) / 2;
750
771
 
751
- // == sync ARIA + data-open quando apre/chiude
752
- CONTENT.addEventListener("toggle", e => {
753
- const open = CONTENT.matches(":popover-open");
754
- BUTTON.setAttribute("aria-expanded", open ? "true" : "false");
755
- pgs(DROPDOWN).state.toggle("open", open);
756
- if (open) {
757
- updatePopoverPosition();
758
- CONTENT.querySelector('a, button, input, select, textarea, [tabindex]:not([tabindex="-1"])')?.focus();
759
- }
760
- });
772
+ if (align === "top") top = triggerRect.top;
773
+ if (align === "bottom") top = triggerRect.bottom - contentRect.height;
774
+ }
761
775
 
762
- window.addEventListener("resize", () => {
763
- if (CONTENT.matches(":popover-open")) updatePopoverPosition();
764
- });
765
- window.addEventListener("scroll", () => {
766
- if (CONTENT.matches(":popover-open")) updatePopoverPosition();
767
- }, true);
776
+ if (side === "left" && left < VIEWPORT_GAP) {
777
+ left = triggerRect.right + VIEWPORT_GAP;
778
+ }
768
779
 
769
- function open() {
770
- if (CONTENT.matches(":popover-open")) return;
771
- updatePopoverPosition();
772
- CONTENT.showPopover();
773
- }
780
+ if (side === "right" && left + contentRect.width > viewportWidth - VIEWPORT_GAP) {
781
+ left = triggerRect.left - contentRect.width - VIEWPORT_GAP;
782
+ }
774
783
 
775
- function close() {
776
- if (!CONTENT.matches(":popover-open")) return;
777
- CONTENT.hidePopover();
778
- }
784
+ left = clamp(left, VIEWPORT_GAP, maxLeft);
785
+
786
+ content.style.setProperty("--dropdown-left", `${Math.round(left)}px`);
787
+ content.style.setProperty("--dropdown-top", `${Math.round(top)}px`);
788
+ }
789
+
790
+ function updateOpenDropdowns() {
791
+ OPEN_DROPDOWNS.forEach(updateposition);
792
+ }
793
+
794
+ function closeDropdown(dropdown) {
795
+ const data = API.get(dropdown);
796
+ if (!data || !data.isOpen()) return;
797
+
798
+ pgs(dropdown).state.remove("open");
799
+ data.trigger.setAttribute("aria-expanded", "false");
800
+ OPEN_DROPDOWNS.delete(dropdown);
801
+ }
802
+
803
+ function openDropdown(dropdown) {
804
+ const data = API.get(dropdown);
805
+ if (!data || data.isOpen()) return;
806
+
807
+ OPEN_DROPDOWNS.forEach(item => {
808
+ if (item !== dropdown) closeDropdown(item);
809
+ });
810
+
811
+ pgs(dropdown).state.add("open");
812
+ data.trigger.setAttribute("aria-expanded", "true");
813
+ OPEN_DROPDOWNS.add(dropdown);
814
+ updateposition(dropdown);
815
+ }
816
+
817
+ function toggleDropdown(dropdown) {
818
+ const data = API.get(dropdown);
819
+ if (!data) return;
820
+
821
+ if (data.isOpen()) closeDropdown(dropdown);
822
+ else openDropdown(dropdown);
823
+ }
779
824
 
780
- function toggle() {
781
- CONTENT.matches(":popover-open") ? close() : open();
825
+ function isInsideAnyDropdown(target) {
826
+ return Array.from(OPEN_DROPDOWNS).some(dropdown => dropdown.contains(target));
827
+ }
828
+
829
+ function PGS_dropdown_init(root = document) {
830
+ getDropdowns(root).forEach((DROPDOWN) => {
831
+ if (API.has(DROPDOWN)) return;
832
+
833
+ const CONTENT = getDropdownContent(DROPDOWN);
834
+ if (!CONTENT) return;
835
+
836
+ const TRIGGER = getDropdownTrigger(DROPDOWN, CONTENT);
837
+ const id = nextDropdownId();
838
+
839
+ if (!TRIGGER.id) TRIGGER.id = `dropdown-btn-${id}`;
840
+ if (!CONTENT.id) CONTENT.id = `dropdown-panel-${id}`;
841
+
842
+ if (TRIGGER.matches("button") && !TRIGGER.hasAttribute("type")) {
843
+ TRIGGER.setAttribute("type", "button");
782
844
  }
783
845
 
784
- API.set(DROPDOWN, {
846
+ TRIGGER.setAttribute("aria-haspopup", "true");
847
+ TRIGGER.setAttribute("aria-controls", CONTENT.id);
848
+ TRIGGER.setAttribute("aria-expanded", String(pgs(DROPDOWN).state.contains("open")));
849
+ CONTENT.setAttribute("aria-labelledby", TRIGGER.id);
850
+
851
+ const data = {
785
852
  element: DROPDOWN,
786
- button: BUTTON,
853
+ trigger: TRIGGER,
787
854
  content: CONTENT,
788
- open,
789
- close,
790
- toggle,
791
- updatePosition: updatePopoverPosition,
855
+ open: () => openDropdown(DROPDOWN),
856
+ close: () => closeDropdown(DROPDOWN),
857
+ toggle: () => toggleDropdown(DROPDOWN),
792
858
  refresh: () => {
793
859
  PGS_dropdown_init(DROPDOWN.parentNode || document);
860
+ updateposition(DROPDOWN);
794
861
  return API.get(DROPDOWN);
795
862
  },
796
- isOpen: () => CONTENT.matches(":popover-open"),
863
+ isOpen: () => pgs(DROPDOWN).state.contains("open")
864
+ };
865
+
866
+ TRIGGER.addEventListener("click", (event) => {
867
+ if (isDropdownContent(event.target)) return;
868
+ event.preventDefault();
869
+ event.stopPropagation();
870
+ toggleDropdown(DROPDOWN);
797
871
  });
872
+
873
+ CONTENT.addEventListener("click", event => event.stopPropagation());
874
+ API.set(DROPDOWN, data);
875
+
876
+ if (data.isOpen()) OPEN_DROPDOWNS.add(DROPDOWN);
877
+ updateposition(DROPDOWN);
798
878
  });
799
879
  }
800
880
 
881
+ document.addEventListener("click", (event) => {
882
+ if (isInsideAnyDropdown(event.target)) return;
883
+ OPEN_DROPDOWNS.forEach(closeDropdown);
884
+ });
885
+
886
+ document.addEventListener("keydown", (event) => {
887
+ if (event.key !== "Escape") return;
888
+ OPEN_DROPDOWNS.forEach(closeDropdown);
889
+ });
890
+
891
+ window.addEventListener("resize", updateOpenDropdowns);
892
+ window.addEventListener("scroll", updateOpenDropdowns, true);
893
+
801
894
  // # INIT
802
895
  PGS_dropdown_init();
803
896
 
@@ -807,7 +900,6 @@ function PGS_dropdown_api(selector) {
807
900
  }
808
901
 
809
902
  const PGS_dropdown = {
810
- PGS_name: "PGS_dropdown",
811
903
  init: PGS_dropdown_init,
812
904
  api: PGS_dropdown_api
813
905
  };
@@ -824,9 +916,7 @@ const PGS_dropdown = {
824
916
  "use strict";
825
917
  __webpack_require__.r(__webpack_exports__);
826
918
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
827
- /* harmony export */ PGS_menu: () => (/* binding */ PGS_menu),
828
- /* harmony export */ PGS_menu_api: () => (/* binding */ PGS_menu_api),
829
- /* harmony export */ PGS_menu_init: () => (/* binding */ PGS_menu_init)
919
+ /* harmony export */ PGS_menu: () => (/* binding */ PGS_menu)
830
920
  /* harmony export */ });
831
921
  /* harmony import */ var _dropdown__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_dropdown */ "./assets/javascript/components/_dropdown.js");
832
922
 
@@ -836,153 +926,52 @@ const API = new WeakMap();
836
926
  //= DROP DOWN MENU
837
927
  function PGS_menu_init(root = document) {
838
928
 
839
- pgs(root).querySelectorAll('menu-horizontal').forEach(MENU => {
929
+ pgs(root).querySelectorAll('menu').forEach(MENU => {
840
930
  if (API.has(MENU)) return;
841
931
 
842
- MENU.querySelectorAll('nav > ul > li.menu-item-has-children').forEach(li => {
843
- if (li.querySelector("ul")) {
844
- const ul = li.querySelector("ul");
845
- if (pgs(li).querySelector("dropdown-button")) return;
932
+ MENU.querySelectorAll('li').forEach(li => {
933
+ const ul = li.querySelector("ul");
934
+
935
+ if (ul) {
846
936
 
847
937
  const button = document.createElement("button");
848
- button.className = "icon-down";
849
938
  button.type = "button";
850
939
  button.innerHTML = "<span>&#9207;</span>";
940
+ pgs(button).add("menu-buttonIcon");
851
941
  li.querySelector("a").insertAdjacentElement("afterend", button);
852
942
 
853
943
  pgs(li).add("dropdown")
854
944
  pgs(button).add("dropdown-button")
855
945
  pgs(button).add("buttonNohover")
856
946
  pgs(ul).add("dropdown-content")
857
- pgs(ul).add("menu-vertical")
947
+
858
948
  }
859
949
  });
860
950
 
861
951
  API.set(MENU, {
862
952
  element: MENU,
863
953
  type: "horizontal",
864
- items: () => Array.from(MENU.querySelectorAll('nav > ul > li')),
865
- submenus: () => Array.from(MENU.querySelectorAll('.menu-item-has-children > ul')),
866
- dropdowns: () => Array.from(MENU.querySelectorAll('.menu-item-has-children')).map(_dropdown__WEBPACK_IMPORTED_MODULE_0__.PGS_dropdown_api).filter(Boolean),
954
+ // items: () => Array.from(MENU.querySelectorAll('nav > ul > li')),
955
+ // submenus: () => Array.from(MENU.querySelectorAll('.menu-item-has-children > ul')),
956
+ // dropdowns: () => Array.from(MENU.querySelectorAll('.menu-item-has-children')).map(PGS_dropdown_api).filter(Boolean),
867
957
  refresh: () => {
868
958
  PGS_menu_init(MENU.parentNode || document);
869
959
  return API.get(MENU);
870
960
  },
871
961
  });
962
+ _dropdown__WEBPACK_IMPORTED_MODULE_0__.PGS_dropdown.init(MENU);
872
963
  });
873
964
 
874
- pgs(root).querySelectorAll('menu-vertical').forEach(MENU => {
875
- if (API.has(MENU)) return;
876
-
877
- MENU.querySelectorAll('.menu-item-has-children').forEach((li, index) => {
878
- const ul = li.querySelector("ul");
879
-
880
- if (!ul) return
881
- if (li.querySelector(":scope > button")) return;
882
-
883
- const button = document.createElement("button");
884
- button.className = "icon-down buttonIcon";
885
- button.type = "button";
886
-
887
- // ID unico per aria-controls
888
- const submenuId = `vertical-submenu-${index}`;
889
- ul.id = submenuId;
890
-
891
- // Stato iniziale
892
- pgs(button).add("buttonIcon")
893
- button.setAttribute("aria-expanded", "false");
894
- button.setAttribute("aria-controls", submenuId);
895
- button.setAttribute("aria-label", "Apri sottomenu");
896
- button.innerHTML = "<span aria-hidden='true'>&#9207;</span>";
897
- li.querySelector("a").insertAdjacentElement("afterend", button);
898
-
899
- function toggleMenu() {
900
- // const isOpena = ul.classList.toggle("open");
901
- const isOpen = pgs(ul).state.toggle("open");
902
- button.setAttribute("aria-expanded", isOpen);
903
- button.setAttribute("aria-label", isOpen ? "Chiudi sottomenu" : "Apri sottomenu");
904
- };
905
-
906
- // Click
907
- button.addEventListener("click", toggleMenu);
908
- button.addEventListener("keydown", (e) => {
909
- if (e.key === "Enter" || e.key === " ") {
910
- e.preventDefault();
911
- toggleMenu();
912
- }
913
- });
914
- });
915
-
916
- function submenu(index) {
917
- return MENU.querySelectorAll('.menu-item-has-children > ul')[index];
918
- }
919
-
920
- function setSubmenu(index, open) {
921
- const ul = submenu(index);
922
- const button = ul?.parentElement?.querySelector(":scope > button");
923
- if (!ul || !button) return;
924
-
925
- pgs(ul).state.toggle("open", open);
926
- button.setAttribute("aria-expanded", String(open));
927
- button.setAttribute("aria-label", open ? "Chiudi sottomenu" : "Apri sottomenu");
928
- }
929
-
930
- API.set(MENU, {
931
- element: MENU,
932
- type: "vertical",
933
- items: () => Array.from(MENU.querySelectorAll(':scope > li')),
934
- submenus: () => Array.from(MENU.querySelectorAll('.menu-item-has-children > ul')),
935
- openSubmenu: (index) => setSubmenu(index, true),
936
- closeSubmenu: (index) => setSubmenu(index, false),
937
- toggleSubmenu: (index) => {
938
- const ul = submenu(index);
939
- if (!ul) return;
940
- setSubmenu(index, !pgs(ul).state.contains("open"));
941
- },
942
- isSubmenuOpen: (index) => {
943
- const ul = submenu(index);
944
- return ul ? pgs(ul).state.contains("open") : false;
945
- },
946
- refresh: () => {
947
- PGS_menu_init(MENU.parentNode || document);
948
- return API.get(MENU);
949
- },
950
- });
951
-
952
- // pgs(document).querySelectorAll('menu-vertical').forEach(MENU => {
953
-
954
- // MENU.querySelectorAll('.menu-item-has-children').forEach(li => {
955
- // if (li.querySelector("ul")) {
956
- // const ul = li.querySelector("ul");
957
-
958
- // const button = document.createElement("button");
959
- // button.className = "icon-down";
960
- // button.type = "button";
961
- // button.innerHTML = "<span>&#9207;</span>";
962
- // li.querySelector("a").insertAdjacentElement("afterend", button);
963
-
964
-
965
- // pgs(button).add("buttonIcon")
966
- // button.addEventListener("click", () => {
967
- // ul.classList.toggle("open")
968
- // })
969
- // }
970
- // });
971
- // });
972
- });
973
- (0,_dropdown__WEBPACK_IMPORTED_MODULE_0__.PGS_dropdown_init)()
974
965
  }
975
966
 
976
- //# INIT PGS_menu
977
967
  PGS_menu_init()
978
968
 
979
- //# API
980
969
  function PGS_menu_api(selector) {
981
970
  return API.get(selector);
982
971
  }
983
972
 
973
+ //# EXPORT
984
974
  const PGS_menu = {
985
- PGS_name: "PGS_menu",
986
975
  init: PGS_menu_init,
987
976
  api: PGS_menu_api
988
977
  };
@@ -1164,7 +1153,6 @@ function PGS_modal_api(selector) {
1164
1153
  }
1165
1154
 
1166
1155
  const PGS_modal = {
1167
- PGS_name: "PGS_modal",
1168
1156
  init: PGS_modal_init,
1169
1157
  api: PGS_modal_api
1170
1158
  };
@@ -1325,17 +1313,16 @@ function PGS_notificationTrigger_init(root = document) {
1325
1313
  }
1326
1314
 
1327
1315
  const PGS_notification = {
1328
- PGS_name: "PGS_notification",
1329
1316
  trigger: PGS_notificationTrigger_init,
1330
1317
  alert: {
1331
- error: (text = "Errore", link = null, timeout = 0, icon = '<i class="fa-solid fa-octagon-xmark"></i>') => fn_notification.initNotification("error", "notification", icon, text, timeout, "stack", link),
1318
+ error: (text = "Errore", link = null, timeout = 0, icon = '<i class="fa-solid fa-circle-xmark"></i>') => fn_notification.initNotification("error", "notification", icon, text, timeout, "stack", link),
1332
1319
  success: (text = "Aggiornato", link = null, timeout = 0, icon = '<i class="fa-solid fa-check"></i>') => fn_notification.initNotification("success", "notification", icon, text, timeout, "stack", link),
1333
1320
  info: (text = "Aggiornamento", link = null, timeout = 0, icon = '<i class="fa-solid fa-circle-info"></i>',) => fn_notification.initNotification("info", "notification", icon, text, timeout, "stack", link),
1334
1321
  warning: (text = "Attenzione", link = null, timeout = 0, icon = '<i class="fa-solid fa-triangle-exclamation"></i>') => fn_notification.initNotification("warning", "notification", icon, text, timeout, "stack", link),
1335
1322
  deleteAll: () => fn_notification.deleteAll("notification")
1336
1323
  },
1337
1324
  toast: {
1338
- error: (text = "Errore", timeout = 4000, icon = '<i class="fa-solid fa-octagon-xmark"></i>',) => fn_notification.initNotification("error", "toast", icon, text, timeout),
1325
+ error: (text = "Errore", timeout = 4000, icon = '<i class="fa-solid fa-circle-xmark"></i>',) => fn_notification.initNotification("error", "toast", icon, text, timeout),
1339
1326
  success: (text = "Aggiornato", timeout = 4000, icon = '<i class="fa-solid fa-check"></i>',) => fn_notification.initNotification("success", "toast", icon, text, timeout),
1340
1327
  info: (text = "Aggiornamento", timeout = 0, icon = '<i class="fa-solid fa-circle-info"></i>',) => fn_notification.initNotification("info", "toast", icon, text, timeout),
1341
1328
  warning: (text = "Attenzione", timeout = 4000, icon = '<i class="fa-solid fa-triangle-exclamation"></i>',) => fn_notification.initNotification("warning", "toast", icon, text, timeout),
@@ -1555,7 +1542,6 @@ function PGS_slides_api(selector) {
1555
1542
  }
1556
1543
 
1557
1544
  const PGS_slides = {
1558
- PGS_name: "PGS_slides",
1559
1545
  init: PGS_slides_init,
1560
1546
  api: PGS_slides_api
1561
1547
  };
@@ -1718,7 +1704,6 @@ function PGS_stepTabs_api(selector) {
1718
1704
  }
1719
1705
 
1720
1706
  const PGS_stepTabs = {
1721
- PGS_name: "PGS_stepTabs",
1722
1707
  init: PGS_stepTabs_init,
1723
1708
  api: PGS_stepTabs_api
1724
1709
  };
@@ -1813,7 +1798,6 @@ function PGS_steps_api(selector) {
1813
1798
  }
1814
1799
 
1815
1800
  const PGS_steps = {
1816
- PGS_name: "PGS_steps",
1817
1801
  init: PGS_steps_init,
1818
1802
  api: PGS_steps_api
1819
1803
  };
@@ -2249,7 +2233,7 @@ function assignCookieRuntimeAttributes({ root, analyticsToggle, acceptAllButton,
2249
2233
  }
2250
2234
 
2251
2235
  //= CookieConsent
2252
- document.addEventListener('DOMContentLoaded', function () {
2236
+ function initCookieConsent() {
2253
2237
  const root = pgs(document).querySelector('cookieConsent');
2254
2238
  if (!root) return;
2255
2239
 
@@ -2359,7 +2343,13 @@ document.addEventListener('DOMContentLoaded', function () {
2359
2343
  } else {
2360
2344
  setBannerVisibility(true);
2361
2345
  }
2362
- });
2346
+ }
2347
+
2348
+ if (document.readyState === 'loading') {
2349
+ document.addEventListener('DOMContentLoaded', initCookieConsent);
2350
+ } else {
2351
+ initCookieConsent();
2352
+ }
2363
2353
 
2364
2354
 
2365
2355
  /***/ },
@@ -2510,17 +2500,17 @@ if (window.innerWidth < 600) {
2510
2500
  /******/ });
2511
2501
  /************************************************************************/
2512
2502
  /******/ // The module cache
2513
- /******/ var __webpack_module_cache__ = {};
2503
+ /******/ const __webpack_module_cache__ = {};
2514
2504
  /******/
2515
2505
  /******/ // The require function
2516
2506
  /******/ function __webpack_require__(moduleId) {
2517
2507
  /******/ // Check if module is in cache
2518
- /******/ var cachedModule = __webpack_module_cache__[moduleId];
2508
+ /******/ const cachedModule = __webpack_module_cache__[moduleId];
2519
2509
  /******/ if (cachedModule !== undefined) {
2520
2510
  /******/ return cachedModule.exports;
2521
2511
  /******/ }
2522
2512
  /******/ // Create a new module (and put it into the cache)
2523
- /******/ var module = __webpack_module_cache__[moduleId] = {
2513
+ /******/ const module = __webpack_module_cache__[moduleId] = {
2524
2514
  /******/ // no module.id needed
2525
2515
  /******/ // no module.loaded needed
2526
2516
  /******/ exports: {}
@@ -2529,7 +2519,7 @@ if (window.innerWidth < 600) {
2529
2519
  /******/ // Execute the module function
2530
2520
  /******/ if (!(moduleId in __webpack_modules__)) {
2531
2521
  /******/ delete __webpack_module_cache__[moduleId];
2532
- /******/ var e = new Error("Cannot find module '" + moduleId + "'");
2522
+ /******/ const e = new Error("Cannot find module '" + moduleId + "'");
2533
2523
  /******/ e.code = 'MODULE_NOT_FOUND';
2534
2524
  /******/ throw e;
2535
2525
  /******/ }
@@ -2544,7 +2534,7 @@ if (window.innerWidth < 600) {
2544
2534
  /******/ (() => {
2545
2535
  /******/ // getDefaultExport function for compatibility with non-harmony modules
2546
2536
  /******/ __webpack_require__.n = (module) => {
2547
- /******/ var getter = module && module.__esModule ?
2537
+ /******/ const getter = module && module.__esModule ?
2548
2538
  /******/ () => (module['default']) :
2549
2539
  /******/ () => (module);
2550
2540
  /******/ __webpack_require__.d(getter, { a: getter });
@@ -2554,11 +2544,26 @@ if (window.innerWidth < 600) {
2554
2544
  /******/
2555
2545
  /******/ /* webpack/runtime/define property getters */
2556
2546
  /******/ (() => {
2557
- /******/ // define getter functions for harmony exports
2547
+ /******/ // define getter/value functions for harmony exports
2558
2548
  /******/ __webpack_require__.d = (exports, definition) => {
2559
- /******/ for(var key in definition) {
2560
- /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
2561
- /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
2549
+ /******/ if(Array.isArray(definition)) {
2550
+ /******/ var i = 0;
2551
+ /******/ while(i < definition.length) {
2552
+ /******/ var key = definition[i++];
2553
+ /******/ var binding = definition[i++];
2554
+ /******/ if(!__webpack_require__.o(exports, key)) {
2555
+ /******/ if(binding === 0) {
2556
+ /******/ Object.defineProperty(exports, key, { enumerable: true, value: definition[i++] });
2557
+ /******/ } else {
2558
+ /******/ Object.defineProperty(exports, key, { enumerable: true, get: binding });
2559
+ /******/ }
2560
+ /******/ } else if(binding === 0) { i++; }
2561
+ /******/ }
2562
+ /******/ } else {
2563
+ /******/ for(var key in definition) {
2564
+ /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
2565
+ /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
2566
+ /******/ }
2562
2567
  /******/ }
2563
2568
  /******/ }
2564
2569
  /******/ };
@@ -2573,7 +2578,7 @@ if (window.innerWidth < 600) {
2573
2578
  /******/ (() => {
2574
2579
  /******/ // define __esModule on exports
2575
2580
  /******/ __webpack_require__.r = (exports) => {
2576
- /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
2581
+ /******/ if(Symbol.toStringTag) {
2577
2582
  /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2578
2583
  /******/ }
2579
2584
  /******/ Object.defineProperty(exports, '__esModule', { value: true });
@@ -2581,7 +2586,7 @@ if (window.innerWidth < 600) {
2581
2586
  /******/ })();
2582
2587
  /******/
2583
2588
  /************************************************************************/
2584
- var __webpack_exports__ = {};
2589
+ let __webpack_exports__ = {};
2585
2590
  // This entry needs to be wrapped in an IIFE because it needs to be in strict mode.
2586
2591
  (() => {
2587
2592
  "use strict";