mypgs 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +33 -0
- package/assets/javascript/_pgs.js +214 -0
- package/assets/javascript/base/_darkmode.js +121 -0
- package/assets/javascript/base/_object.js +42 -0
- package/assets/javascript/components/_accordion.js +77 -0
- package/assets/javascript/components/_dropdown.js +107 -0
- package/assets/javascript/components/_exeNotifications.js +85 -0
- package/assets/javascript/components/_menu.js +92 -0
- package/assets/javascript/components/_modals.js +123 -0
- package/assets/javascript/components/_slides.js +183 -0
- package/assets/javascript/components/_steps.js +27 -0
- package/assets/javascript/components/_tabs.js +134 -0
- package/assets/javascript/functions/_formValidate.js +217 -0
- package/assets/javascript/functions/_notifications.js +74 -0
- package/assets/javascript/functions/_scrollY.js +77 -0
- package/assets/javascript/functions/_sendForm.js +100 -0
- package/assets/javascript/index.js +20 -0
- package/assets/javascript/patterns/_cookieConsent.js +209 -0
- package/assets/javascript/patterns/_header.js +134 -0
- package/assets/javascript/pgs.d.ts +23 -0
- package/assets/scss/base/_body.scss +151 -0
- package/assets/scss/base/_color.scss +56 -0
- package/assets/scss/base/_general.scss +58 -0
- package/assets/scss/base/_heading.scss +20 -0
- package/assets/scss/base/_html.scss +4 -0
- package/assets/scss/base/_reset.scss +15 -0
- package/assets/scss/base/_variables.scss +39 -0
- package/assets/scss/components/_accordion.scss +91 -0
- package/assets/scss/components/_breadcumbs.scss +40 -0
- package/assets/scss/components/_button.scss +28 -0
- package/assets/scss/components/_dropdown.scss +106 -0
- package/assets/scss/components/_form.scss +53 -0
- package/assets/scss/components/_logo.scss +51 -0
- package/assets/scss/components/_menu.scss +23 -0
- package/assets/scss/components/_modals.scss +120 -0
- package/assets/scss/components/_notification.scss +193 -0
- package/assets/scss/components/_searchbar.scss +68 -0
- package/assets/scss/components/_slides.scss +198 -0
- package/assets/scss/components/_steps.scss +111 -0
- package/assets/scss/components/_table.scss +59 -0
- package/assets/scss/components/_tabs.scss +69 -0
- package/assets/scss/components/_tooltip.scss +16 -0
- package/assets/scss/index.scss +64 -0
- package/assets/scss/layout/_flex.scss +47 -0
- package/assets/scss/layout/_gap.scss +12 -0
- package/assets/scss/layout/_grid.scss +11 -0
- package/assets/scss/layout/_layout.scss +41 -0
- package/assets/scss/layout/_pageShell.scss +171 -0
- package/assets/scss/mixin/_mx-base.scss +126 -0
- package/assets/scss/mixin/_mx-button.scss +186 -0
- package/assets/scss/mixin/_mx-card.scss +77 -0
- package/assets/scss/mixin/_mx-color.scss +34 -0
- package/assets/scss/mixin/_mx-form-addon.scss +180 -0
- package/assets/scss/mixin/_mx-form.scss +512 -0
- package/assets/scss/mixin/_mx-menu.scss +154 -0
- package/assets/scss/mixin/_mx-responsive.scss +353 -0
- package/assets/scss/mixin/_mx-semantic.scss +147 -0
- package/assets/scss/mixin/mixin.scss +36 -0
- package/assets/scss/patterns/_cookieConsent.scss +101 -0
- package/assets/scss/patterns/_footer.scss +180 -0
- package/assets/scss/patterns/_header.scss +143 -0
- package/dist/css/index.css +7026 -0
- package/dist/css/index.css.map +1 -0
- package/dist/css/index.min.css +1 -0
- package/dist/index.d.ts +24 -0
- package/dist/javascript/index.js +2034 -0
- package/dist/javascript/index.js.map +1 -0
- package/dist/javascript/index.min.js +1 -0
- package/package.json +40 -0
- package/templates/components/md-breadcumbs.html +23 -0
- package/templates/components/md-menu.html +6 -0
- package/templates/components/md-notification.html +10 -0
- package/templates/components/md-searchbar.html +24 -0
- package/templates/components/md-tooltip.html +5 -0
- package/templates/layout/md-body.html +20 -0
- package/templates/layout/md-cookieConsent.html +51 -0
- package/templates/layout/md-footer.html +16 -0
- package/templates/layout/md-header.html +43 -0
- package/webpack.config.js +131 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { pgs_dropdown } from "./_dropdown";
|
|
2
|
+
|
|
3
|
+
//= DROP DOWN MENU
|
|
4
|
+
export function PGS_menu() {
|
|
5
|
+
|
|
6
|
+
pgs(document).querySelectorAll('menu-horizontal').forEach(MENU => {
|
|
7
|
+
|
|
8
|
+
MENU.querySelectorAll('nav > ul > li.menu-item-has-children').forEach(li => {
|
|
9
|
+
if (li.querySelector("ul")) {
|
|
10
|
+
const ul = li.querySelector("ul");
|
|
11
|
+
|
|
12
|
+
const button = document.createElement("button");
|
|
13
|
+
button.className = "icon-down";
|
|
14
|
+
button.type = "button";
|
|
15
|
+
button.innerHTML = "<span>⏷</span>";
|
|
16
|
+
li.querySelector("a").insertAdjacentElement("afterend", button);
|
|
17
|
+
|
|
18
|
+
pgs(li).add("dropdown")
|
|
19
|
+
pgs(button).add("dropdown-button")
|
|
20
|
+
pgs(button).add("buttonNohover")
|
|
21
|
+
pgs(ul).add("dropdown-content")
|
|
22
|
+
pgs(ul).add("menu-vertical")
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
pgs(document).querySelectorAll('menu-vertical').forEach(MENU => {
|
|
28
|
+
|
|
29
|
+
MENU.querySelectorAll('.menu-item-has-children').forEach((li, index) => {
|
|
30
|
+
const ul = li.querySelector("ul");
|
|
31
|
+
|
|
32
|
+
if (!ul) return
|
|
33
|
+
|
|
34
|
+
const button = document.createElement("button");
|
|
35
|
+
button.className = "icon-down buttonIcon";
|
|
36
|
+
button.type = "button";
|
|
37
|
+
|
|
38
|
+
// ID unico per aria-controls
|
|
39
|
+
const submenuId = `vertical-submenu-${index}`;
|
|
40
|
+
ul.id = submenuId;
|
|
41
|
+
|
|
42
|
+
// Stato iniziale
|
|
43
|
+
pgs(button).add("buttonIcon")
|
|
44
|
+
button.setAttribute("aria-expanded", "false");
|
|
45
|
+
button.setAttribute("aria-controls", submenuId);
|
|
46
|
+
button.setAttribute("aria-label", "Apri sottomenu");
|
|
47
|
+
button.innerHTML = "<span aria-hidden='true'>⏷</span>";
|
|
48
|
+
li.querySelector("a").insertAdjacentElement("afterend", button);
|
|
49
|
+
|
|
50
|
+
function toggleMenu() {
|
|
51
|
+
// const isOpena = ul.classList.toggle("open");
|
|
52
|
+
const isOpen = pgs(ul).state.toggle("open");
|
|
53
|
+
button.setAttribute("aria-expanded", isOpen);
|
|
54
|
+
button.setAttribute("aria-label", isOpen ? "Chiudi sottomenu" : "Apri sottomenu");
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
// Click
|
|
58
|
+
button.addEventListener("click", toggleMenu);
|
|
59
|
+
button.addEventListener("keydown", (e) => {
|
|
60
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
61
|
+
e.preventDefault();
|
|
62
|
+
toggleMenu();
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// pgs(document).querySelectorAll('menu-vertical').forEach(MENU => {
|
|
68
|
+
|
|
69
|
+
// MENU.querySelectorAll('.menu-item-has-children').forEach(li => {
|
|
70
|
+
// if (li.querySelector("ul")) {
|
|
71
|
+
// const ul = li.querySelector("ul");
|
|
72
|
+
|
|
73
|
+
// const button = document.createElement("button");
|
|
74
|
+
// button.className = "icon-down";
|
|
75
|
+
// button.type = "button";
|
|
76
|
+
// button.innerHTML = "<span>⏷</span>";
|
|
77
|
+
// li.querySelector("a").insertAdjacentElement("afterend", button);
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
// pgs(button).add("buttonIcon")
|
|
81
|
+
// button.addEventListener("click", () => {
|
|
82
|
+
// ul.classList.toggle("open")
|
|
83
|
+
// })
|
|
84
|
+
// }
|
|
85
|
+
// });
|
|
86
|
+
// });
|
|
87
|
+
});
|
|
88
|
+
pgs_dropdown()
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
//# INIT PGS_menu
|
|
92
|
+
PGS_menu()
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
//# MODAL
|
|
2
|
+
PGS_modal()
|
|
3
|
+
export function PGS_modal(selector = "modal") {
|
|
4
|
+
pgs(document).querySelectorAll(selector).forEach(MODAL => {
|
|
5
|
+
|
|
6
|
+
const BUTTON_OPEN = pgs(MODAL).querySelector("modal-button");
|
|
7
|
+
const DIALOG = MODAL.querySelector("dialog");
|
|
8
|
+
if (!BUTTON_OPEN || !DIALOG) return;
|
|
9
|
+
|
|
10
|
+
//== SELECTOR
|
|
11
|
+
const DOMButtonClose = '<button pgs="buttonClose modal-close" type="button" tabindex="0" aria-label="Chiudi"><i class="fa-solid fa-close"></i></button>';
|
|
12
|
+
const modalContentHeader = pgs(MODAL)?.querySelector("modal-dialog-content-header")
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
//== OPTION ATTRIBUTES MODAL
|
|
16
|
+
const disableBackdropClose = pgs(MODAL).option.contains("disableBackdropClose")
|
|
17
|
+
const data_history = pgs(MODAL).option.contains("history");
|
|
18
|
+
const data_container = pgs(MODAL).option.getValueBrackets("containerID");
|
|
19
|
+
const data_containerPGS = pgs(MODAL).option.getValueBrackets("containerPGS");
|
|
20
|
+
|
|
21
|
+
//== OPTION ATTRIBUTES DIALOG
|
|
22
|
+
const topLevel = pgs(DIALOG).option.contains("topLevel")
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
//== BUTTON CLOSE
|
|
26
|
+
if (pgs(MODAL).querySelector("modal-close")) null
|
|
27
|
+
else if (modalContentHeader) modalContentHeader.insertAdjacentHTML("beforeend", DOMButtonClose)
|
|
28
|
+
else DIALOG.insertAdjacentHTML("beforeend", DOMButtonClose)
|
|
29
|
+
const BUTTON_CLOSE = pgs(MODAL).querySelector("modal-close")
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
//== SET
|
|
33
|
+
pgs(DIALOG).add("dialog modal-dialog");
|
|
34
|
+
|
|
35
|
+
//== BUTTON OPEN
|
|
36
|
+
BUTTON_OPEN.setAttribute("role", "button");
|
|
37
|
+
BUTTON_OPEN.setAttribute("aria-label", "apri modale");
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
//== POSITION
|
|
41
|
+
if(!topLevel){
|
|
42
|
+
if (data_container) document.querySelector("#" + data_container)?.append(DIALOG);
|
|
43
|
+
else if (data_containerPGS) pgs(document).querySelector(data_containerPGS)?.append(DIALOG);
|
|
44
|
+
else document.body.append(DIALOG);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
//+ FN STATUS
|
|
49
|
+
function statusModal(status = true) {
|
|
50
|
+
BUTTON_OPEN?.setAttribute("aria-expanded", status);
|
|
51
|
+
DIALOG?.setAttribute("aria-expanded", status);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
//+ FN OPEN
|
|
55
|
+
function openModal(e) {
|
|
56
|
+
e?.stopImmediatePropagation();
|
|
57
|
+
if (!DIALOG.open) document.querySelectorAll("dialog[open]").forEach((dlg) => dlg.close());
|
|
58
|
+
statusModal(true);
|
|
59
|
+
DIALOG.open ? closeModal(e) : topLevel ? DIALOG.showModal() : DIALOG.show();
|
|
60
|
+
// modalCustomEvents('modal:open', { event: e });
|
|
61
|
+
MODAL.dispatchEvent(new CustomEvent('modal:open'));
|
|
62
|
+
DIALOG.dispatchEvent(new CustomEvent('modal:open'));
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
//+ FN CLOSE
|
|
66
|
+
function closeModal(e) {
|
|
67
|
+
e?.stopImmediatePropagation()
|
|
68
|
+
statusModal(false);
|
|
69
|
+
DIALOG.close();
|
|
70
|
+
// modalCustomEvents('modal:close', { event: e });
|
|
71
|
+
MODAL.dispatchEvent(new CustomEvent('modal:close'));
|
|
72
|
+
DIALOG.dispatchEvent(new CustomEvent('modal:close'));
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
//+ fn OPEN ON HISTORY
|
|
76
|
+
function openModalOnHistory() {
|
|
77
|
+
const params = new URLSearchParams(window.location.search);
|
|
78
|
+
if (params.get('modal') !== BUTTON_OPEN.id) return;
|
|
79
|
+
document.getElementById(BUTTON_OPEN.id)?.scrollIntoView({ behavior: 'smooth' });
|
|
80
|
+
openModal();
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
//= OPEN
|
|
85
|
+
BUTTON_OPEN.addEventListener("click", (e) => openModal(e));
|
|
86
|
+
BUTTON_OPEN.addEventListener("keypress", (e) => !DIALOG.open && (e.key === "Enter" || e.key === " ") && openModal(e));
|
|
87
|
+
|
|
88
|
+
//= CLOSE
|
|
89
|
+
DIALOG.addEventListener("close", () => statusModal(false));
|
|
90
|
+
DIALOG.addEventListener("click", e => { if (e.target == DIALOG && !disableBackdropClose) closeModal(e) });
|
|
91
|
+
BUTTON_CLOSE?.addEventListener("click", e => closeModal(e));
|
|
92
|
+
|
|
93
|
+
//= UPDATE HISTORY
|
|
94
|
+
if (data_history && BUTTON_OPEN.id) {
|
|
95
|
+
setTimeout(openModalOnHistory, 1);
|
|
96
|
+
|
|
97
|
+
//== Aggiorna URL quando cambia l'attributo "open" del dialog
|
|
98
|
+
const obs = new MutationObserver(() => {
|
|
99
|
+
let isOpen = DIALOG.hasAttribute("open");
|
|
100
|
+
try {
|
|
101
|
+
const url = new URL(window.location.href);
|
|
102
|
+
const params = new URLSearchParams(url.search);
|
|
103
|
+
isOpen ? params.set('modal', BUTTON_OPEN.id) : params.delete('modal');
|
|
104
|
+
url.search = params.toString() ? `?${params.toString()}` : "";
|
|
105
|
+
window.history.pushState({ modal: BUTTON_OPEN.id, open: isOpen }, "", url);
|
|
106
|
+
} catch (_) { }
|
|
107
|
+
});
|
|
108
|
+
obs.observe(DIALOG, { attributes: true, attributeFilter: ["open"] });
|
|
109
|
+
|
|
110
|
+
//== Gestisce back/forward del browser per aprire/chiudere il dialog coerentemente
|
|
111
|
+
window.addEventListener("popstate", () => {
|
|
112
|
+
try {
|
|
113
|
+
const params = new URLSearchParams(window.location.search);
|
|
114
|
+
const shouldOpen = params.get('modal') === BUTTON_OPEN.id;
|
|
115
|
+
if (shouldOpen && !DIALOG.open) DIALOG.showModal();
|
|
116
|
+
if (!shouldOpen && DIALOG.open) closeModal()
|
|
117
|
+
} catch (_) { }
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
//# INIT PGS_modal
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { PGS_scrollHorizontal } from "../functions/_scrollY"
|
|
2
|
+
const API = new WeakMap();
|
|
3
|
+
|
|
4
|
+
class PGS_Slides {
|
|
5
|
+
//- CONSTRUCTOR
|
|
6
|
+
constructor({ selector, viewRatio = 0.97, optionIntersectionObserver = {}, scrollOptions = {} } = {}) {
|
|
7
|
+
this.selector = selector;
|
|
8
|
+
this.viewRatio = viewRatio;
|
|
9
|
+
|
|
10
|
+
this.optionIntersectionObserver = {
|
|
11
|
+
threshold: Array.from({ length: 101 }, (_, i) => i / 100), // 0%,1%,2%...100%
|
|
12
|
+
rootMargin: "0px",
|
|
13
|
+
...optionIntersectionObserver,
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
this.scrollOptions = {
|
|
17
|
+
behavior: "smooth",
|
|
18
|
+
inline: "center",
|
|
19
|
+
block: "nearest",
|
|
20
|
+
container: "nearest",
|
|
21
|
+
...scrollOptions,
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
this.container = this.selector ? pgs(this.selector).querySelector("slides-container") : null;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
//+ CREATE BUTTON
|
|
28
|
+
#createButtonsAndDots() {
|
|
29
|
+
const EL = this.selector
|
|
30
|
+
|
|
31
|
+
//== PULSANTI
|
|
32
|
+
if (!pgs(EL).querySelector('slides-prec') && !pgs(EL).querySelector('slides-next')) {
|
|
33
|
+
EL.insertAdjacentHTML("afterbegin", `<button pgs="slides-prec button" type="button" class="precButton" aria-label="slide precedente"> <span> <i class="fa-solid fa-arrow-left"></i></span></button>`);
|
|
34
|
+
EL.insertAdjacentHTML("beforeend", `<button pgs="slides-next button" type="button" class="nextButton" aria-label="prossima slide"> <span> <i class="fa-solid fa-arrow-right"></i></span></button>`);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
//== DOTS
|
|
38
|
+
if (!pgs(EL).querySelector('slides-dots')) {
|
|
39
|
+
EL.insertAdjacentHTML("beforeend", `<div pgs="slides-dots" class="slides-dots"></div>`);
|
|
40
|
+
|
|
41
|
+
Array.from(this.container.children).forEach(() => {
|
|
42
|
+
pgs(EL).querySelector('slides-dots')
|
|
43
|
+
.insertAdjacentHTML("beforeend", `<button type="button" class="slide-dot" aria-label="vai alla prossima slide"></button>`);
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
//+ PREV
|
|
49
|
+
#previousSlide() {
|
|
50
|
+
const currents = this.container.querySelectorAll('.view');
|
|
51
|
+
let current;
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
if (pgs(this.selector).option.contains('singleScroll')) current = currents[currents.length - 1];
|
|
55
|
+
else current = currents[0];
|
|
56
|
+
|
|
57
|
+
const prev = current?.previousElementSibling;
|
|
58
|
+
|
|
59
|
+
prev?.scrollIntoView(this.scrollOptions);
|
|
60
|
+
prev?.focus({ preventScroll: true });
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
//+ NEXT
|
|
64
|
+
#nextSlide() {
|
|
65
|
+
const currents = this.container.querySelectorAll('.view');
|
|
66
|
+
let current;
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
if (pgs(this.selector).option.contains('singleScroll')) current = currents[0];
|
|
71
|
+
else current = currents[currents.length - 1];
|
|
72
|
+
|
|
73
|
+
const next = current?.nextElementSibling;
|
|
74
|
+
console.log(current, next);
|
|
75
|
+
|
|
76
|
+
next?.scrollIntoView(this.scrollOptions);
|
|
77
|
+
next?.focus({ preventScroll: true });
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
//+ GO TO NUMBER SLIDE
|
|
81
|
+
#goToNumberSlide(index) {
|
|
82
|
+
this.container.children[index].scrollIntoView(this.scrollOptions)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
//+ CALLBACK
|
|
86
|
+
#callback(allLi, container, precButton, nextButton, dots) {
|
|
87
|
+
allLi.forEach(LI => {
|
|
88
|
+
const visiblePercent = 0.9 + LI.intersectionRatio * 0.1;
|
|
89
|
+
const isView = visiblePercent >= 0.98;
|
|
90
|
+
|
|
91
|
+
//== SCROLL ANIMATION
|
|
92
|
+
if (!pgs(LI.target).option.contains('notScrollAnimation')) {
|
|
93
|
+
LI.target.firstElementChild.style.setProperty('--visible-percent', `${visiblePercent}`);
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
//== VIEW & NOT-VIEW
|
|
97
|
+
LI.target.classList.toggle("view", isView);
|
|
98
|
+
LI.target.classList.toggle("notView", !isView);
|
|
99
|
+
|
|
100
|
+
//== VIEW PREC e NEXT
|
|
101
|
+
const all = LI.target.parentNode.children;
|
|
102
|
+
const atStart = all[0].classList.contains("view");
|
|
103
|
+
const atEnd = all[all.length - 1].classList.contains("view");
|
|
104
|
+
nextButton.disabled = atEnd;
|
|
105
|
+
precButton.disabled = atStart;
|
|
106
|
+
nextButton.setAttribute('aria-disabled', String(atEnd));
|
|
107
|
+
precButton.setAttribute('aria-disabled', String(atStart));
|
|
108
|
+
|
|
109
|
+
//== ACTIVE DOT
|
|
110
|
+
const viewElements = Array.from(container.children).filter(el => el.classList.contains('view'));
|
|
111
|
+
dots.forEach((btn, i) => {
|
|
112
|
+
const isActive = viewElements.some(el => Array.from(container.children).indexOf(el) === i);
|
|
113
|
+
btn.classList.toggle('active', isActive);
|
|
114
|
+
btn.setAttribute('aria-current', isActive ? 'true' : 'false');
|
|
115
|
+
});
|
|
116
|
+
})
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
//= EXECUTE
|
|
120
|
+
execute() {
|
|
121
|
+
const slides = this.selector;
|
|
122
|
+
if (!this.container) return
|
|
123
|
+
|
|
124
|
+
//== elements
|
|
125
|
+
this.#createButtonsAndDots();
|
|
126
|
+
const precButton = pgs(slides).querySelector('slides-prec');
|
|
127
|
+
const nextButton = pgs(slides).querySelector('slides-next');
|
|
128
|
+
const dots = Array.from(pgs(slides).querySelector('slides-dots').children);
|
|
129
|
+
|
|
130
|
+
//== option
|
|
131
|
+
const notScrollWithMouse = pgs(slides).option.contains('notScrollWithMouse');
|
|
132
|
+
|
|
133
|
+
//== scroll
|
|
134
|
+
if (!notScrollWithMouse) PGS_scrollHorizontal(this.container, 5);
|
|
135
|
+
|
|
136
|
+
//==Listener: DOT, PREC, NEXT
|
|
137
|
+
dots.forEach((dot, index) => dot.addEventListener("click", e => this.#goToNumberSlide(index)));
|
|
138
|
+
precButton.addEventListener("click", e => this.#previousSlide(), { passive: true });
|
|
139
|
+
nextButton.addEventListener("click", e => this.#nextSlide(), { passive: true });
|
|
140
|
+
|
|
141
|
+
//== observer
|
|
142
|
+
const observer = new IntersectionObserver(
|
|
143
|
+
(allLi) => this.#callback(allLi, this.container, precButton, nextButton, dots),
|
|
144
|
+
{ root: this.container, ...this.optionIntersectionObserver }
|
|
145
|
+
);
|
|
146
|
+
Array.from(this.container.children).forEach(allLi => observer.observe(allLi));
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
//- API
|
|
150
|
+
API.set(this.selector, {
|
|
151
|
+
element: this.selector,
|
|
152
|
+
container: this.container,
|
|
153
|
+
previous: () => this.#previousSlide(),
|
|
154
|
+
next: () => this.#nextSlide(),
|
|
155
|
+
goTo: (index) => this.#goToNumberSlide(index),
|
|
156
|
+
getCurrentIndexes: () => Array.from(this.container.children).map((el, i) => el.classList.contains("view") ? i : -1).filter(i => i !== -1),
|
|
157
|
+
getCurrentElements: () => Array.from(this.container.children).filter(el => el.classList.contains("view")),
|
|
158
|
+
getTotal: () => this.container.children.length,
|
|
159
|
+
isAtStart: () => this.container.children[0]?.classList.contains("view") || false,
|
|
160
|
+
isAtEnd: () => {
|
|
161
|
+
const children = this.container.children;
|
|
162
|
+
const last = children[children.length - 1];
|
|
163
|
+
return last?.classList.contains("view") || false;
|
|
164
|
+
},
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
PGS_slides_init();
|
|
169
|
+
|
|
170
|
+
//# INIT
|
|
171
|
+
export function PGS_slides_init(root = document) {
|
|
172
|
+
pgs(root).querySelectorAll("slides").forEach(el => {
|
|
173
|
+
if (API.has(el)) return;
|
|
174
|
+
|
|
175
|
+
const instance = new PGS_Slides({ selector: el });
|
|
176
|
+
instance.execute();
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
//# API
|
|
181
|
+
export function PGS_slides_api(selector) {
|
|
182
|
+
return API.get(selector);
|
|
183
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
|
|
2
|
+
export function PGS_ol() {
|
|
3
|
+
pgs(document).querySelectorAll("steps").forEach(steps => {
|
|
4
|
+
|
|
5
|
+
pgs(steps).querySelectorAll("steps-step").forEach((li, index) => {
|
|
6
|
+
|
|
7
|
+
//= CIRCLE
|
|
8
|
+
let circleLi;
|
|
9
|
+
if (!pgs(li).querySelector("steps-step-circle")) {
|
|
10
|
+
circleLi = document.createElement("span");
|
|
11
|
+
pgs(circleLi).add("steps-step-circle")
|
|
12
|
+
circleLi.textContent = index + 1;
|
|
13
|
+
li.insertAdjacentElement("afterbegin", circleLi);
|
|
14
|
+
} else{
|
|
15
|
+
circleLi = pgs(li).querySelector("steps-step-circle");
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
//= line
|
|
19
|
+
const line = document.createElement("span");
|
|
20
|
+
pgs(line).add("steps-step-line")
|
|
21
|
+
li.insertAdjacentElement("afterbegin", line);
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
//# INIT PGS_ol
|
|
27
|
+
PGS_ol()
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
const API = new WeakMap();
|
|
2
|
+
PGS_tabs()
|
|
3
|
+
|
|
4
|
+
export function PGS_tabs() {
|
|
5
|
+
pgs(document).querySelectorAll("tabs").forEach(tabsWizard => {
|
|
6
|
+
|
|
7
|
+
//= INIT
|
|
8
|
+
// if (tabsWizard.getAttribute("data-initialize") == "true") return;
|
|
9
|
+
// tabsWizard.setAttribute("data-initialize", "true");
|
|
10
|
+
|
|
11
|
+
//= SELECTOR
|
|
12
|
+
const prev = pgs(tabsWizard).querySelector("tabs-prev")
|
|
13
|
+
const next = pgs(tabsWizard).querySelector("tabs-next")
|
|
14
|
+
const restart = pgs(tabsWizard).querySelector("tabs-restart")
|
|
15
|
+
const dots = pgs(tabsWizard).querySelector("tabs-dots")
|
|
16
|
+
const tabsContainer = pgs(tabsWizard).querySelector("tabs-container");
|
|
17
|
+
const allTab = pgs(tabsContainer).querySelectorAll("tab");
|
|
18
|
+
|
|
19
|
+
//= SETTING
|
|
20
|
+
const total = allTab.length;
|
|
21
|
+
const defaultTabLocked = Array.from(allTab).filter(tab => tab.getAttribute("data-tab-locked") === "true")
|
|
22
|
+
let current = 0;
|
|
23
|
+
prev.disabled = true;
|
|
24
|
+
|
|
25
|
+
//- CREAZIONE DOTS
|
|
26
|
+
const tabDots = [];
|
|
27
|
+
if (dots) {
|
|
28
|
+
dots.innerHTML = "";
|
|
29
|
+
|
|
30
|
+
allTab.forEach((tab, index) => {
|
|
31
|
+
|
|
32
|
+
const iconClass = tab.getAttribute("data-tab-icon") || "fa-circle";
|
|
33
|
+
|
|
34
|
+
const dot = document.createElement("button");
|
|
35
|
+
dot.type = "button";
|
|
36
|
+
dot.className = "tab-dot";
|
|
37
|
+
dot.setAttribute("data-step", index);
|
|
38
|
+
dot.innerHTML = `<i class="fa-solid ${iconClass}"></i>`;
|
|
39
|
+
|
|
40
|
+
dot.addEventListener("click", () => {
|
|
41
|
+
if (dot.classList.contains("is-completed")) {
|
|
42
|
+
goTo(index, true);
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
dots.appendChild(dot);
|
|
47
|
+
tabDots.push(dot);
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
//+ DOTS
|
|
52
|
+
function updateDots() {
|
|
53
|
+
tabDots.forEach((dot, i) => {
|
|
54
|
+
dot.classList.toggle("is-active", i === current);
|
|
55
|
+
dot.classList.toggle("is-completed", i < current);
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
//+ Step
|
|
60
|
+
function goTo(index) {
|
|
61
|
+
current = Math.min(Math.max(index, 0), total - 1);
|
|
62
|
+
const tab = allTab[current]
|
|
63
|
+
|
|
64
|
+
prev.disabled = (current === 0);
|
|
65
|
+
next.disabled = (current === total - 1 || tab.getAttribute("data-tab-locked") === "true");
|
|
66
|
+
|
|
67
|
+
allTab.forEach((tab, i) => tab.classList.toggle("is-active", i === current));
|
|
68
|
+
tab?.focus();
|
|
69
|
+
tabsWizard?.scrollIntoView({ behavior: "smooth", block: "start" });
|
|
70
|
+
updateDots();
|
|
71
|
+
tabsWizard.dispatchEvent(new CustomEvent('tabs:change', { detail: { current, total } }));
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
//+ restart
|
|
75
|
+
function restartTab() {
|
|
76
|
+
goTo(0);
|
|
77
|
+
defaultTabLocked.forEach(tab => tab.setAttribute("data-tab-locked", "true"));
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
//= INIT
|
|
81
|
+
goTo(0);
|
|
82
|
+
|
|
83
|
+
//= data-tab-locked
|
|
84
|
+
const observer = new MutationObserver(() => goTo(current));
|
|
85
|
+
allTab?.forEach(tabEl => observer.observe(tabEl, { attributes: true, attributeFilter: ["data-tab-locked"], }));
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
//= Click su Avanti/Indietro
|
|
89
|
+
prev?.addEventListener("click", e => goTo(current - 1));
|
|
90
|
+
next?.addEventListener("click", e => goTo(current + 1));
|
|
91
|
+
restart?.addEventListener("click", e => restartTab(), { capture: true });
|
|
92
|
+
|
|
93
|
+
//-(API)
|
|
94
|
+
// tabsWizard.addEventListener("tabs:reset", () => restartTab());
|
|
95
|
+
API.set(tabsWizard, {
|
|
96
|
+
restart: restartTab,
|
|
97
|
+
goTo,
|
|
98
|
+
next: () => goTo(current + 1),
|
|
99
|
+
prev: () => goTo(current - 1),
|
|
100
|
+
toggleLock: (step, lock = true) => typeof step === "number" && allTab[step] && (allTab[step].setAttribute("data-tab-locked", lock.toString()), goTo(current)),
|
|
101
|
+
getCurrent: () => current,
|
|
102
|
+
getState: () => ({ current, total }),
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export function PGS_tabs_api(selector) {
|
|
108
|
+
return API.get(selector);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
/*
|
|
113
|
+
/ EXAMPLE
|
|
114
|
+
// vai allo step 2
|
|
115
|
+
w.dispatchEvent(new CustomEvent("tabs:go", { detail: { step: 2 } }));
|
|
116
|
+
|
|
117
|
+
// next
|
|
118
|
+
w.dispatchEvent(new CustomEvent("tabs:next"));
|
|
119
|
+
|
|
120
|
+
// prev
|
|
121
|
+
w.dispatchEvent(new CustomEvent("tabs:prev"));
|
|
122
|
+
|
|
123
|
+
// reset a 0 senza relock
|
|
124
|
+
w.dispatchEvent(new CustomEvent("tabs:reset"));
|
|
125
|
+
|
|
126
|
+
// lock step 3
|
|
127
|
+
w.dispatchEvent(new CustomEvent("tabs:toggle-lock", { detail: { step: 3, lock: true } }));
|
|
128
|
+
|
|
129
|
+
// unlock step 3
|
|
130
|
+
w.dispatchEvent(new CustomEvent("tabs:toggle-lock", { detail: { step: 3, lock: false } }));
|
|
131
|
+
|
|
132
|
+
// leggi stato
|
|
133
|
+
w.dispatchEvent(new CustomEvent("tabs:get", { detail: { reply: (state) => console.log(state) } }));
|
|
134
|
+
*/
|