mypgs 1.3.2 → 1.3.4

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 +16 -6
  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 +264 -1179
  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 +264 -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,20 +33,21 @@ __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
49
 
50
+
50
51
  /***/ },
51
52
 
52
53
  /***/ "./assets/javascript/_pgs.js"
@@ -282,7 +283,6 @@ function pgs(root) {
282
283
  const api = createBasePgs();
283
284
  api.state = createState("pgs-state");
284
285
  api.option = createOption("pgs-option");
285
- api.modules = createOption("pgs-modules");
286
286
  return api;
287
287
  }
288
288
 
@@ -312,6 +312,22 @@ pgs.registerImport = function (...modules) {
312
312
  return pgs;
313
313
  };
314
314
 
315
+ pgs.registerModules = function (modules = {}) {
316
+ Object.entries(modules).forEach(([name, module]) => {
317
+ const key = String(name || "").trim();
318
+ if (!key) return;
319
+
320
+ const hasOwn = Object.prototype.hasOwnProperty.call(pgs, key);
321
+ if (hasOwn && pgs[key] !== module) {
322
+ throw new Error(`pgs.registerModules(): "${key}" e' gia' definito su pgs`);
323
+ }
324
+
325
+ pgs[key] = module;
326
+ });
327
+
328
+ return pgs;
329
+ };
330
+
315
331
  pgs.import = function (...names) {
316
332
  return names.flat().reduce((imports, name) => {
317
333
  const key = String(name || "").trim().replace(/^pgs[_-\s]*/i, "").toLowerCase();
@@ -527,17 +543,27 @@ __webpack_require__.r(__webpack_exports__);
527
543
  /* harmony export */ });
528
544
  //= ACCORDION
529
545
  const API = new WeakMap();
546
+ let accordionId = 0;
547
+
548
+ function nextAccordionId() {
549
+ accordionId += 1;
550
+ return accordionId;
551
+ }
552
+
553
+ function directPgsChild(element, token) {
554
+ return Array.from(element.children).find(child => pgs(child).contains(token));
555
+ }
530
556
 
531
557
  function PGS_accordion_init(root = document) {
532
- pgs(root).querySelectorAll("accordion").forEach((accordion, index) => {
558
+ pgs(root).querySelectorAll("accordion").forEach((accordion) => {
533
559
  if (API.has(accordion)) return;
534
560
 
535
- const BUTTON = pgs(accordion).querySelector("accordion-button");
536
- const CONTENT = pgs(accordion).querySelector("accordion-content");
561
+ const BUTTON = directPgsChild(accordion, "accordion-button");
562
+ const CONTENT = directPgsChild(accordion, "accordion-content");
537
563
  if (!BUTTON || !CONTENT) return;
538
564
 
539
565
  //== ID univoci per aria-controls / aria-labelledby
540
- const ID = index + 1;
566
+ const ID = nextAccordionId();
541
567
  const btnId = `acc-btn-${ID}`;
542
568
  const panelId = `acc-panel-${ID}`;
543
569
 
@@ -547,12 +573,12 @@ function PGS_accordion_init(root = document) {
547
573
  //== Accessibilità (setup una volta)
548
574
  BUTTON.setAttribute("role", "button");
549
575
  BUTTON.setAttribute("tabindex", "0");
550
- BUTTON.setAttribute("id", btnId);
551
- BUTTON.setAttribute("aria-controls", panelId);
576
+ if (!BUTTON.id) BUTTON.setAttribute("id", btnId);
552
577
 
553
- CONTENT.setAttribute("id", panelId);
578
+ if (!CONTENT.id) CONTENT.setAttribute("id", panelId);
579
+ BUTTON.setAttribute("aria-controls", CONTENT.id);
554
580
  CONTENT.setAttribute("role", "region");
555
- CONTENT.setAttribute("aria-labelledby", btnId);
581
+ CONTENT.setAttribute("aria-labelledby", BUTTON.id);
556
582
 
557
583
  //+ Accessibility (applica stato aperto/chiuso)
558
584
  function accordionAccessibility(isOpen, button, content) {
@@ -637,7 +663,6 @@ function PGS_accordion_api(selector) {
637
663
  }
638
664
 
639
665
  const PGS_accordion = {
640
- PGS_name: "PGS_accordion",
641
666
  init: PGS_accordion_init,
642
667
  api: PGS_accordion_api
643
668
  };
@@ -654,150 +679,205 @@ const PGS_accordion = {
654
679
  "use strict";
655
680
  __webpack_require__.r(__webpack_exports__);
656
681
  /* 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)
682
+ /* harmony export */ PGS_dropdown: () => (/* binding */ PGS_dropdown)
660
683
  /* harmony export */ });
661
- // + dropdown (Popover API)
684
+ // + dropdown
662
685
  const API = new WeakMap();
686
+ const OPEN_DROPDOWNS = new Set();
687
+ const VIEWPORT_GAP = 8;
688
+ let dropdownId = 0;
663
689
 
664
- function PGS_dropdown_init(root = document) {
665
- pgs(root).querySelectorAll("dropdown").forEach((DROPDOWN, index) => {
666
- if (API.has(DROPDOWN)) return;
690
+ function nextDropdownId() {
691
+ dropdownId += 1;
692
+ return dropdownId;
693
+ }
667
694
 
668
- const BUTTON = pgs(DROPDOWN).querySelector("dropdown-button");
669
- const CONTENT = pgs(DROPDOWN).querySelector("dropdown-content");
695
+ function isDropdownContent(element) {
696
+ return element instanceof Element && pgs(element).contains("dropdown-content");
697
+ }
670
698
 
671
- if (!BUTTON || !CONTENT) return;
699
+ function getDropdownTrigger(dropdown, content) {
700
+ const children = Array.from(dropdown.children).filter(child => child !== content);
701
+ const dropdownButton = children.find(child => pgs(child).contains("dropdown-button"));
672
702
 
673
- // = INIT
674
- if (DROPDOWN.getAttribute("data-initialize") === "true") return;
675
- DROPDOWN.setAttribute("data-initialize", "true");
703
+ return dropdownButton || children.find(child => !isDropdownContent(child)) || dropdown;
704
+ }
676
705
 
677
- // == CSS dropdown-anchor
678
- const ANCHOR_NAME = `--dropdown-anchor-${index}`;
679
- DROPDOWN.style.setProperty("--dropdown-anchor", ANCHOR_NAME);
706
+ function getDropdownContent(dropdown) {
707
+ return Array.from(dropdown.children).find(isDropdownContent) || pgs(dropdown).querySelector("dropdown-content");
708
+ }
680
709
 
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);
710
+ function getDropdowns(root) {
711
+ const dropdowns = root instanceof Element && pgs(root).contains("dropdown") ? [root] : [];
712
+ dropdowns.push(...pgs(root).querySelectorAll("dropdown"));
713
+ return dropdowns;
714
+ }
689
715
 
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
- );
716
+ function getposition(dropdown) {
717
+ const option = pgs(dropdown).option;
718
+ const optionValue = option.getValueBrackets("position");
719
+ const raw = (optionValue || "bottom center").trim().toLowerCase();
720
+ const parts = raw.split(/\s+/).filter(Boolean);
721
+ const side = parts.find(part => ["top", "right", "bottom", "left"].includes(part)) || "bottom";
722
+ const align = parts.find(part => ["top", "right", "bottom", "left", "center"].includes(part) && part !== side) || "center";
732
723
 
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
- };
724
+ return { side, align };
725
+ }
737
726
 
738
- BUTTON.addEventListener("click", e => {
739
- if (!USE_FALLBACK_POSITIONING) return;
727
+ function clamp(value, min, max) {
728
+ return Math.min(Math.max(value, min), max);
729
+ }
740
730
 
741
- e.preventDefault();
742
- if (CONTENT.matches(":popover-open")) {
743
- CONTENT.hidePopover();
744
- return;
745
- }
731
+ function updateposition(dropdown) {
732
+ const data = API.get(dropdown);
733
+ if (!data || !data.isOpen()) return;
734
+
735
+ const { trigger, content } = data;
736
+ const { side, align } = getposition(dropdown);
737
+ const triggerRect = trigger.getBoundingClientRect();
738
+ const contentRect = content.getBoundingClientRect();
739
+ const viewportWidth = document.documentElement.clientWidth;
740
+ const maxLeft = Math.max(VIEWPORT_GAP, viewportWidth - contentRect.width - VIEWPORT_GAP);
741
+ let left = triggerRect.left + (triggerRect.width - contentRect.width) / 2;
742
+ let top = triggerRect.bottom + VIEWPORT_GAP;
743
+
744
+ if (side === "top" || side === "bottom") {
745
+ top = side === "top"
746
+ ? triggerRect.top - contentRect.height - VIEWPORT_GAP
747
+ : triggerRect.bottom + VIEWPORT_GAP;
748
+
749
+ if (align === "left") left = triggerRect.left;
750
+ if (align === "right") left = triggerRect.right - contentRect.width;
751
+ }
746
752
 
747
- updatePopoverPosition();
748
- CONTENT.showPopover();
749
- });
753
+ if (side === "left" || side === "right") {
754
+ left = side === "left"
755
+ ? triggerRect.left - contentRect.width - VIEWPORT_GAP
756
+ : triggerRect.right + VIEWPORT_GAP;
757
+ top = triggerRect.top + (triggerRect.height - contentRect.height) / 2;
750
758
 
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
- });
759
+ if (align === "top") top = triggerRect.top;
760
+ if (align === "bottom") top = triggerRect.bottom - contentRect.height;
761
+ }
761
762
 
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);
763
+ if (side === "left" && left < VIEWPORT_GAP) {
764
+ left = triggerRect.right + VIEWPORT_GAP;
765
+ }
768
766
 
769
- function open() {
770
- if (CONTENT.matches(":popover-open")) return;
771
- updatePopoverPosition();
772
- CONTENT.showPopover();
773
- }
767
+ if (side === "right" && left + contentRect.width > viewportWidth - VIEWPORT_GAP) {
768
+ left = triggerRect.left - contentRect.width - VIEWPORT_GAP;
769
+ }
774
770
 
775
- function close() {
776
- if (!CONTENT.matches(":popover-open")) return;
777
- CONTENT.hidePopover();
778
- }
771
+ left = clamp(left, VIEWPORT_GAP, maxLeft);
772
+
773
+ content.style.setProperty("--dropdown-left", `${Math.round(left)}px`);
774
+ content.style.setProperty("--dropdown-top", `${Math.round(top)}px`);
775
+ }
776
+
777
+ function updateOpenDropdowns() {
778
+ OPEN_DROPDOWNS.forEach(updateposition);
779
+ }
780
+
781
+ function closeDropdown(dropdown) {
782
+ const data = API.get(dropdown);
783
+ if (!data || !data.isOpen()) return;
784
+
785
+ pgs(dropdown).state.remove("open");
786
+ data.trigger.setAttribute("aria-expanded", "false");
787
+ OPEN_DROPDOWNS.delete(dropdown);
788
+ }
789
+
790
+ function openDropdown(dropdown) {
791
+ const data = API.get(dropdown);
792
+ if (!data || data.isOpen()) return;
793
+
794
+ OPEN_DROPDOWNS.forEach(item => {
795
+ if (item !== dropdown) closeDropdown(item);
796
+ });
797
+
798
+ pgs(dropdown).state.add("open");
799
+ data.trigger.setAttribute("aria-expanded", "true");
800
+ OPEN_DROPDOWNS.add(dropdown);
801
+ updateposition(dropdown);
802
+ }
803
+
804
+ function toggleDropdown(dropdown) {
805
+ const data = API.get(dropdown);
806
+ if (!data) return;
807
+
808
+ if (data.isOpen()) closeDropdown(dropdown);
809
+ else openDropdown(dropdown);
810
+ }
779
811
 
780
- function toggle() {
781
- CONTENT.matches(":popover-open") ? close() : open();
812
+ function isInsideAnyDropdown(target) {
813
+ return Array.from(OPEN_DROPDOWNS).some(dropdown => dropdown.contains(target));
814
+ }
815
+
816
+ function PGS_dropdown_init(root = document) {
817
+ getDropdowns(root).forEach((DROPDOWN) => {
818
+ if (API.has(DROPDOWN)) return;
819
+
820
+ const CONTENT = getDropdownContent(DROPDOWN);
821
+ if (!CONTENT) return;
822
+
823
+ const TRIGGER = getDropdownTrigger(DROPDOWN, CONTENT);
824
+ const id = nextDropdownId();
825
+
826
+ if (!TRIGGER.id) TRIGGER.id = `dropdown-btn-${id}`;
827
+ if (!CONTENT.id) CONTENT.id = `dropdown-panel-${id}`;
828
+
829
+ if (TRIGGER.matches("button") && !TRIGGER.hasAttribute("type")) {
830
+ TRIGGER.setAttribute("type", "button");
782
831
  }
783
832
 
784
- API.set(DROPDOWN, {
833
+ TRIGGER.setAttribute("aria-haspopup", "true");
834
+ TRIGGER.setAttribute("aria-controls", CONTENT.id);
835
+ TRIGGER.setAttribute("aria-expanded", String(pgs(DROPDOWN).state.contains("open")));
836
+ CONTENT.setAttribute("aria-labelledby", TRIGGER.id);
837
+
838
+ const data = {
785
839
  element: DROPDOWN,
786
- button: BUTTON,
840
+ trigger: TRIGGER,
787
841
  content: CONTENT,
788
- open,
789
- close,
790
- toggle,
791
- updatePosition: updatePopoverPosition,
842
+ open: () => openDropdown(DROPDOWN),
843
+ close: () => closeDropdown(DROPDOWN),
844
+ toggle: () => toggleDropdown(DROPDOWN),
792
845
  refresh: () => {
793
846
  PGS_dropdown_init(DROPDOWN.parentNode || document);
847
+ updateposition(DROPDOWN);
794
848
  return API.get(DROPDOWN);
795
849
  },
796
- isOpen: () => CONTENT.matches(":popover-open"),
850
+ isOpen: () => pgs(DROPDOWN).state.contains("open")
851
+ };
852
+
853
+ TRIGGER.addEventListener("click", (event) => {
854
+ if (isDropdownContent(event.target)) return;
855
+ event.preventDefault();
856
+ event.stopPropagation();
857
+ toggleDropdown(DROPDOWN);
797
858
  });
859
+
860
+ CONTENT.addEventListener("click", event => event.stopPropagation());
861
+ API.set(DROPDOWN, data);
862
+
863
+ if (data.isOpen()) OPEN_DROPDOWNS.add(DROPDOWN);
864
+ updateposition(DROPDOWN);
798
865
  });
799
866
  }
800
867
 
868
+ document.addEventListener("click", (event) => {
869
+ if (isInsideAnyDropdown(event.target)) return;
870
+ OPEN_DROPDOWNS.forEach(closeDropdown);
871
+ });
872
+
873
+ document.addEventListener("keydown", (event) => {
874
+ if (event.key !== "Escape") return;
875
+ OPEN_DROPDOWNS.forEach(closeDropdown);
876
+ });
877
+
878
+ window.addEventListener("resize", updateOpenDropdowns);
879
+ window.addEventListener("scroll", updateOpenDropdowns, true);
880
+
801
881
  // # INIT
802
882
  PGS_dropdown_init();
803
883
 
@@ -807,7 +887,6 @@ function PGS_dropdown_api(selector) {
807
887
  }
808
888
 
809
889
  const PGS_dropdown = {
810
- PGS_name: "PGS_dropdown",
811
890
  init: PGS_dropdown_init,
812
891
  api: PGS_dropdown_api
813
892
  };
@@ -824,9 +903,7 @@ const PGS_dropdown = {
824
903
  "use strict";
825
904
  __webpack_require__.r(__webpack_exports__);
826
905
  /* 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)
906
+ /* harmony export */ PGS_menu: () => (/* binding */ PGS_menu)
830
907
  /* harmony export */ });
831
908
  /* harmony import */ var _dropdown__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_dropdown */ "./assets/javascript/components/_dropdown.js");
832
909
 
@@ -836,153 +913,52 @@ const API = new WeakMap();
836
913
  //= DROP DOWN MENU
837
914
  function PGS_menu_init(root = document) {
838
915
 
839
- pgs(root).querySelectorAll('menu-horizontal').forEach(MENU => {
916
+ pgs(root).querySelectorAll('menu').forEach(MENU => {
840
917
  if (API.has(MENU)) return;
841
918
 
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;
919
+ MENU.querySelectorAll('li').forEach(li => {
920
+ const ul = li.querySelector("ul");
921
+
922
+ if (ul) {
846
923
 
847
924
  const button = document.createElement("button");
848
- button.className = "icon-down";
849
925
  button.type = "button";
850
926
  button.innerHTML = "<span>&#9207;</span>";
927
+ pgs(button).add("menu-buttonIcon");
851
928
  li.querySelector("a").insertAdjacentElement("afterend", button);
852
929
 
853
930
  pgs(li).add("dropdown")
854
931
  pgs(button).add("dropdown-button")
855
932
  pgs(button).add("buttonNohover")
856
933
  pgs(ul).add("dropdown-content")
857
- pgs(ul).add("menu-vertical")
934
+
858
935
  }
859
936
  });
860
937
 
861
938
  API.set(MENU, {
862
939
  element: MENU,
863
940
  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),
941
+ // items: () => Array.from(MENU.querySelectorAll('nav > ul > li')),
942
+ // submenus: () => Array.from(MENU.querySelectorAll('.menu-item-has-children > ul')),
943
+ // dropdowns: () => Array.from(MENU.querySelectorAll('.menu-item-has-children')).map(PGS_dropdown_api).filter(Boolean),
867
944
  refresh: () => {
868
945
  PGS_menu_init(MENU.parentNode || document);
869
946
  return API.get(MENU);
870
947
  },
871
948
  });
949
+ _dropdown__WEBPACK_IMPORTED_MODULE_0__.PGS_dropdown.init(MENU);
872
950
  });
873
951
 
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
952
  }
975
953
 
976
- //# INIT PGS_menu
977
954
  PGS_menu_init()
978
955
 
979
- //# API
980
956
  function PGS_menu_api(selector) {
981
957
  return API.get(selector);
982
958
  }
983
959
 
960
+ //# EXPORT
984
961
  const PGS_menu = {
985
- PGS_name: "PGS_menu",
986
962
  init: PGS_menu_init,
987
963
  api: PGS_menu_api
988
964
  };
@@ -1164,7 +1140,6 @@ function PGS_modal_api(selector) {
1164
1140
  }
1165
1141
 
1166
1142
  const PGS_modal = {
1167
- PGS_name: "PGS_modal",
1168
1143
  init: PGS_modal_init,
1169
1144
  api: PGS_modal_api
1170
1145
  };
@@ -1325,17 +1300,16 @@ function PGS_notificationTrigger_init(root = document) {
1325
1300
  }
1326
1301
 
1327
1302
  const PGS_notification = {
1328
- PGS_name: "PGS_notification",
1329
1303
  trigger: PGS_notificationTrigger_init,
1330
1304
  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),
1305
+ 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
1306
  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
1307
  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
1308
  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
1309
  deleteAll: () => fn_notification.deleteAll("notification")
1336
1310
  },
1337
1311
  toast: {
1338
- error: (text = "Errore", timeout = 4000, icon = '<i class="fa-solid fa-octagon-xmark"></i>',) => fn_notification.initNotification("error", "toast", icon, text, timeout),
1312
+ error: (text = "Errore", timeout = 4000, icon = '<i class="fa-solid fa-circle-xmark"></i>',) => fn_notification.initNotification("error", "toast", icon, text, timeout),
1339
1313
  success: (text = "Aggiornato", timeout = 4000, icon = '<i class="fa-solid fa-check"></i>',) => fn_notification.initNotification("success", "toast", icon, text, timeout),
1340
1314
  info: (text = "Aggiornamento", timeout = 0, icon = '<i class="fa-solid fa-circle-info"></i>',) => fn_notification.initNotification("info", "toast", icon, text, timeout),
1341
1315
  warning: (text = "Attenzione", timeout = 4000, icon = '<i class="fa-solid fa-triangle-exclamation"></i>',) => fn_notification.initNotification("warning", "toast", icon, text, timeout),
@@ -1555,7 +1529,6 @@ function PGS_slides_api(selector) {
1555
1529
  }
1556
1530
 
1557
1531
  const PGS_slides = {
1558
- PGS_name: "PGS_slides",
1559
1532
  init: PGS_slides_init,
1560
1533
  api: PGS_slides_api
1561
1534
  };
@@ -1718,7 +1691,6 @@ function PGS_stepTabs_api(selector) {
1718
1691
  }
1719
1692
 
1720
1693
  const PGS_stepTabs = {
1721
- PGS_name: "PGS_stepTabs",
1722
1694
  init: PGS_stepTabs_init,
1723
1695
  api: PGS_stepTabs_api
1724
1696
  };
@@ -1813,7 +1785,6 @@ function PGS_steps_api(selector) {
1813
1785
  }
1814
1786
 
1815
1787
  const PGS_steps = {
1816
- PGS_name: "PGS_steps",
1817
1788
  init: PGS_steps_init,
1818
1789
  api: PGS_steps_api
1819
1790
  };
@@ -2249,7 +2220,7 @@ function assignCookieRuntimeAttributes({ root, analyticsToggle, acceptAllButton,
2249
2220
  }
2250
2221
 
2251
2222
  //= CookieConsent
2252
- document.addEventListener('DOMContentLoaded', function () {
2223
+ function initCookieConsent() {
2253
2224
  const root = pgs(document).querySelector('cookieConsent');
2254
2225
  if (!root) return;
2255
2226
 
@@ -2359,7 +2330,13 @@ document.addEventListener('DOMContentLoaded', function () {
2359
2330
  } else {
2360
2331
  setBannerVisibility(true);
2361
2332
  }
2362
- });
2333
+ }
2334
+
2335
+ if (document.readyState === 'loading') {
2336
+ document.addEventListener('DOMContentLoaded', initCookieConsent);
2337
+ } else {
2338
+ initCookieConsent();
2339
+ }
2363
2340
 
2364
2341
 
2365
2342
  /***/ },
@@ -2510,17 +2487,17 @@ if (window.innerWidth < 600) {
2510
2487
  /******/ });
2511
2488
  /************************************************************************/
2512
2489
  /******/ // The module cache
2513
- /******/ var __webpack_module_cache__ = {};
2490
+ /******/ const __webpack_module_cache__ = {};
2514
2491
  /******/
2515
2492
  /******/ // The require function
2516
2493
  /******/ function __webpack_require__(moduleId) {
2517
2494
  /******/ // Check if module is in cache
2518
- /******/ var cachedModule = __webpack_module_cache__[moduleId];
2495
+ /******/ const cachedModule = __webpack_module_cache__[moduleId];
2519
2496
  /******/ if (cachedModule !== undefined) {
2520
2497
  /******/ return cachedModule.exports;
2521
2498
  /******/ }
2522
2499
  /******/ // Create a new module (and put it into the cache)
2523
- /******/ var module = __webpack_module_cache__[moduleId] = {
2500
+ /******/ const module = __webpack_module_cache__[moduleId] = {
2524
2501
  /******/ // no module.id needed
2525
2502
  /******/ // no module.loaded needed
2526
2503
  /******/ exports: {}
@@ -2529,7 +2506,7 @@ if (window.innerWidth < 600) {
2529
2506
  /******/ // Execute the module function
2530
2507
  /******/ if (!(moduleId in __webpack_modules__)) {
2531
2508
  /******/ delete __webpack_module_cache__[moduleId];
2532
- /******/ var e = new Error("Cannot find module '" + moduleId + "'");
2509
+ /******/ const e = new Error("Cannot find module '" + moduleId + "'");
2533
2510
  /******/ e.code = 'MODULE_NOT_FOUND';
2534
2511
  /******/ throw e;
2535
2512
  /******/ }
@@ -2544,7 +2521,7 @@ if (window.innerWidth < 600) {
2544
2521
  /******/ (() => {
2545
2522
  /******/ // getDefaultExport function for compatibility with non-harmony modules
2546
2523
  /******/ __webpack_require__.n = (module) => {
2547
- /******/ var getter = module && module.__esModule ?
2524
+ /******/ const getter = module && module.__esModule ?
2548
2525
  /******/ () => (module['default']) :
2549
2526
  /******/ () => (module);
2550
2527
  /******/ __webpack_require__.d(getter, { a: getter });
@@ -2554,11 +2531,26 @@ if (window.innerWidth < 600) {
2554
2531
  /******/
2555
2532
  /******/ /* webpack/runtime/define property getters */
2556
2533
  /******/ (() => {
2557
- /******/ // define getter functions for harmony exports
2534
+ /******/ // define getter/value functions for harmony exports
2558
2535
  /******/ __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] });
2536
+ /******/ if(Array.isArray(definition)) {
2537
+ /******/ var i = 0;
2538
+ /******/ while(i < definition.length) {
2539
+ /******/ var key = definition[i++];
2540
+ /******/ var binding = definition[i++];
2541
+ /******/ if(!__webpack_require__.o(exports, key)) {
2542
+ /******/ if(binding === 0) {
2543
+ /******/ Object.defineProperty(exports, key, { enumerable: true, value: definition[i++] });
2544
+ /******/ } else {
2545
+ /******/ Object.defineProperty(exports, key, { enumerable: true, get: binding });
2546
+ /******/ }
2547
+ /******/ } else if(binding === 0) { i++; }
2548
+ /******/ }
2549
+ /******/ } else {
2550
+ /******/ for(var key in definition) {
2551
+ /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
2552
+ /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
2553
+ /******/ }
2562
2554
  /******/ }
2563
2555
  /******/ }
2564
2556
  /******/ };
@@ -2573,7 +2565,7 @@ if (window.innerWidth < 600) {
2573
2565
  /******/ (() => {
2574
2566
  /******/ // define __esModule on exports
2575
2567
  /******/ __webpack_require__.r = (exports) => {
2576
- /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
2568
+ /******/ if(Symbol.toStringTag) {
2577
2569
  /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2578
2570
  /******/ }
2579
2571
  /******/ Object.defineProperty(exports, '__esModule', { value: true });
@@ -2581,7 +2573,7 @@ if (window.innerWidth < 600) {
2581
2573
  /******/ })();
2582
2574
  /******/
2583
2575
  /************************************************************************/
2584
- var __webpack_exports__ = {};
2576
+ let __webpack_exports__ = {};
2585
2577
  // This entry needs to be wrapped in an IIFE because it needs to be in strict mode.
2586
2578
  (() => {
2587
2579
  "use strict";