@teddy-dev/frontend 1.0.1
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/algolia/algolia-loader.js +56 -0
- package/algolia/algolia-search.js +222 -0
- package/auth/teddy-auth-login.js +29 -0
- package/auth/teddy-auth-profile.js +58 -0
- package/auth/teddy-auth-register.js +52 -0
- package/auth/teddy-auth-reset.js +39 -0
- package/auth/teddy-auth.js +92 -0
- package/bantoa/bantoa-product.js +64 -0
- package/bantoa/bantoa-search.js +46 -0
- package/bantoa/bantoa-stylemix.js +43 -0
- package/bantoa/bantoa.js +21 -0
- package/cart/teddy-cart-controller.js +163 -0
- package/cart/teddy-cart-customer.js +86 -0
- package/cart/teddy-cart-discounts.js +55 -0
- package/cart/teddy-cart-promo-apply.js +24 -0
- package/cart/teddy-cart-promo-error.js +38 -0
- package/cart/teddy-cart-promo-loading.js +20 -0
- package/cart/teddy-cart-promo.js +96 -0
- package/components/mc-btn.js +38 -0
- package/components/mc-card-render.js +33 -0
- package/components/mc-cart-counter.js +14 -0
- package/components/mc-cart-error.js +35 -0
- package/components/mc-cart-quantity.js +43 -0
- package/components/mc-cart-remove.js +32 -0
- package/components/mc-copy.js +33 -0
- package/components/mc-element.js +84 -0
- package/components/mc-form-errors.js +35 -0
- package/components/mc-form-success.js +31 -0
- package/components/mc-form.js +223 -0
- package/components/mc-input-area.js +13 -0
- package/components/mc-input-checkbox-group.js +52 -0
- package/components/mc-input-checkbox.js +12 -0
- package/components/mc-input-password.js +39 -0
- package/components/mc-input-places.js +43 -0
- package/components/mc-input-quantity.js +43 -0
- package/components/mc-input-select.js +14 -0
- package/components/mc-input-text.js +12 -0
- package/components/mc-input.js +137 -0
- package/components/mc-loader.js +21 -0
- package/components/mc-modal.js +69 -0
- package/components/mc-password-eye.js +24 -0
- package/components/mc-password-tips.js +60 -0
- package/components/mc-qrcode.js +41 -0
- package/components/mc-range.js +108 -0
- package/components/mc-read-more.js +56 -0
- package/components/mc-recommended.js +50 -0
- package/components/mc-referrer.js +20 -0
- package/components/mc-splash-controller.js +32 -0
- package/components/mc-splash-link.js +65 -0
- package/components/mc-stoq.js +30 -0
- package/components/mc-swiper.js +333 -0
- package/components/mc-video.js +61 -0
- package/css/bootstrap-lg.css +2762 -0
- package/css/bootstrap-lg.min.css +1 -0
- package/css/bootstrap-md.css +2762 -0
- package/css/bootstrap-md.min.css +1 -0
- package/css/bootstrap-sm.css +2762 -0
- package/css/bootstrap-sm.min.css +1 -0
- package/css/bootstrap-xl.css +2790 -0
- package/css/bootstrap-xl.min.css +1 -0
- package/css/bootstrap-xxl.css +2762 -0
- package/css/bootstrap-xxl.min.css +1 -0
- package/css/bootstrap.css +9824 -0
- package/css/bootstrap.min.css +5 -0
- package/css/mc-form-errors.css +3 -0
- package/css/mc-loader.css +6 -0
- package/css/mc-password-eye.css +6 -0
- package/css/mc-password-tips.css +6 -0
- package/css/mc-read-more.css +14 -0
- package/css/mc-video.css +4 -0
- package/css/mc-wishlist-hero-btn.css +7 -0
- package/loader.js +110 -0
- package/loyalty/teddy-loyalty-create.js +40 -0
- package/loyalty/teddy-loyalty-redeem.js +38 -0
- package/loyalty/teddy-loyalty.js +214 -0
- package/package.json +20 -0
- package/res/mc-events.js +43 -0
- package/res/mc-shopify.js +439 -0
- package/res/mc-utils.js +119 -0
- package/res/mc-vue.js +9350 -0
- package/returns/teddy-return-iban.js +115 -0
- package/returns/teddy-return-list.js +165 -0
- package/returns/teddy-return-request.js +353 -0
- package/scripts/publish-store.js +62 -0
- package/test/auth-login-error.json +4 -0
- package/test/auth-login-success.json +13 -0
- package/test/auth-password-change-error.json +4 -0
- package/test/auth-password-change-success.json +3 -0
- package/test/auth-register-error.json +4 -0
- package/test/auth-register-success.json +12 -0
- package/test/auth-reset-error.json +4 -0
- package/test/auth-reset-success.json +3 -0
- package/test/loyalty-error.json +4 -0
- package/test/loyalty-noinfo.json +18 -0
- package/test/loyalty-redeem-error.json +4 -0
- package/test/loyalty-redeem-success.json +11 -0
- package/test/loyalty-success.json +143 -0
- package/test/returns-create-success.json +1 -0
- package/test/returns-get-success.json +35 -0
- package/test/returns-get-tracking.json +30 -0
- package/test/returns-list-empty.json +4 -0
- package/test/returns-list-success.json +59 -0
- package/test/returns-search-manual.json +67 -0
- package/test/returns-search-success.json +76 -0
- package/test/wishlist-error.json +4 -0
- package/test/wishlist-success.json +3 -0
- package/wishlist/teddy-wishlist-btn.js +55 -0
- package/wishlist/teddy-wishlist-clear.js +18 -0
- package/wishlist/teddy-wishlist-counter.js +35 -0
- package/wishlist/teddy-wishlist-item.js +46 -0
- package/wishlist/teddy-wishlist-page.js +59 -0
- package/wishlist/teddy-wishlist.js +131 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import '../res/mc-events.js';
|
|
2
|
+
await loadComponent('./components/mc-input.js', false);
|
|
3
|
+
|
|
4
|
+
class McInputQuantity extends McInput {
|
|
5
|
+
|
|
6
|
+
connectedCallback() {
|
|
7
|
+
this.init();
|
|
8
|
+
this.querySelector('[data-plus]')?.addEventListener('click', this.plus.bind(this));
|
|
9
|
+
this.querySelector('[data-minus]')?.addEventListener('click', this.minus.bind(this));
|
|
10
|
+
this.input.addEventListener('keyup', this.change.bind(this));
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
plus = () => {
|
|
14
|
+
const step = parseInt(this.input.step) || 1;
|
|
15
|
+
this.setValue(parseInt(this.input.value) + step);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
change = (e) => {
|
|
19
|
+
if(this.input.value === '') return;
|
|
20
|
+
const newValue = parseInt(this.input.value);
|
|
21
|
+
this.setValue(newValue);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
setValue = (value) => {
|
|
25
|
+
const max = parseInt(this.input.max);
|
|
26
|
+
const min = parseInt(this.input.min);
|
|
27
|
+
if((isNaN(max) || value <= max) && (isNaN(min) || value >= min)){
|
|
28
|
+
this.input.value = value;
|
|
29
|
+
McShopify.customEvent(MCEVENTS.QUANTITY_CHANGED, {value:value}, this);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
minus = () => {
|
|
34
|
+
const step = parseInt(this.input.step) || 1;
|
|
35
|
+
this.setValue(parseInt(this.input.value) - step);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
}
|
|
39
|
+
if(!customElements.get('mc-input-quantity')) {
|
|
40
|
+
customElements.define('mc-input-quantity', McInputQuantity);
|
|
41
|
+
}
|
|
42
|
+
window.McInputQuantity = McInputQuantity;
|
|
43
|
+
export default McInputQuantity;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
await loadComponent('./components/mc-input.js', false); // Carica il componente Input
|
|
2
|
+
await loadComponent('./res/mc-shopify.js', false);
|
|
3
|
+
|
|
4
|
+
class McInputSelect extends McInput {
|
|
5
|
+
connectedCallback() {
|
|
6
|
+
this.input = this.querySelector('select');
|
|
7
|
+
this.init();
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
if(!customElements.get('mc-input-select')) {
|
|
11
|
+
customElements.define('mc-input-select', McInputSelect);
|
|
12
|
+
}
|
|
13
|
+
window.McInputSelect = McInputSelect;
|
|
14
|
+
export default McInputSelect;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
await loadComponent('./components/mc-input.js', false);
|
|
2
|
+
|
|
3
|
+
class McInputText extends McInput {
|
|
4
|
+
connectedCallback() {
|
|
5
|
+
this.init();
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
if(!customElements.get('mc-input-text')) {
|
|
9
|
+
customElements.define('mc-input-text', McInputText);
|
|
10
|
+
}
|
|
11
|
+
window.McInputText = McInputText;
|
|
12
|
+
export default McInputText;
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import '../res/mc-events.js';
|
|
2
|
+
await loadComponent('./components/mc-element.js', false);
|
|
3
|
+
await loadComponent('./res/mc-utils.js', false);
|
|
4
|
+
await loadComponent('./res/mc-shopify.js', false);
|
|
5
|
+
|
|
6
|
+
// Definizione della classe custom element McInput
|
|
7
|
+
class McInput extends McElement {
|
|
8
|
+
input; // Riferimento all'elemento input
|
|
9
|
+
error; // Container per il messaggio di errore
|
|
10
|
+
errorText; // Testo del messaggio di errore
|
|
11
|
+
isValid; // Stato di validità dell'input
|
|
12
|
+
static ERROR_CLASS = 'is-invalid'; // Classe CSS per indicare un errore
|
|
13
|
+
|
|
14
|
+
// Metodo di inizializzazione: collega input, error e listener
|
|
15
|
+
init = () => {
|
|
16
|
+
this.error = this.querySelector('[data-error]'); // Seleziona il container per l'errore
|
|
17
|
+
this.input = this.input ? this.input : this.querySelector('input'); // Seleziona l'elemento input
|
|
18
|
+
|
|
19
|
+
// Controlli di presenza elementi e traduzioni
|
|
20
|
+
if (!this.input) { console.error('McInput: No input element found'); return; }
|
|
21
|
+
if(!this.error){ console.error('McInput: No error container found'); return; }
|
|
22
|
+
if(!window.theme?.t) { console.error('McInput: Translations not available'); return; }
|
|
23
|
+
if(!window.theme.t.errors) { console.error('McInput: Translations for errors not available'); return; }
|
|
24
|
+
|
|
25
|
+
// Listener per validazione su keyup, blur e change
|
|
26
|
+
this.setEvents();
|
|
27
|
+
this.autosubmit(); // Configura autosubmit se richiesto
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
setEvents = () => {
|
|
31
|
+
const triggers = this.dataset.triggers ? this.dataset.triggers.split(',').map(t => t.trim()) : ['keyup', 'change', 'blur'];
|
|
32
|
+
triggers.forEach(trigger => {
|
|
33
|
+
this.input.addEventListener(trigger, this.validate.bind(this));
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Valida l'input utilizzando la proprietà `validity` e aggiorna errorText
|
|
38
|
+
validate = (e) => {
|
|
39
|
+
this.isValid = this.input.checkValidity(); // Controlla la validità dell'input
|
|
40
|
+
if (!this.isValid) {
|
|
41
|
+
// Gestione dei vari tipi di errori di validazione HTML5
|
|
42
|
+
if (this.input.validity.badMcInput) {
|
|
43
|
+
this.validateType();
|
|
44
|
+
} else if (this.input.validity.valueMissing) {
|
|
45
|
+
this.errorText = theme.t.errors.required;
|
|
46
|
+
} else if (this.input.validity.typeMismatch) {
|
|
47
|
+
this.validateType();
|
|
48
|
+
} else if (this.input.validity.tooShort) {
|
|
49
|
+
this.errorText = theme.t.errors.minLength.replace('{{ minlength }}', this.input.minLength);
|
|
50
|
+
} else if (this.input.validity.tooLong) {
|
|
51
|
+
this.errorText = theme.t.errors.maxLength.replace('{{ maxlength }}', this.input.maxLength);
|
|
52
|
+
} else if (this.input.validity.rangeUnderflow) {
|
|
53
|
+
this.errorText = theme.t.errors.min.replace('{{ min }}', this.input.min);
|
|
54
|
+
} else if (this.input.validity.rangeOverflow) {
|
|
55
|
+
this.errorText = theme.t.errors.max.replace('{{ max }}', this.input.max);
|
|
56
|
+
} else if (this.input.validity.stepMismatch) {
|
|
57
|
+
this.errorText = theme.t.errors.step;
|
|
58
|
+
} else if (this.input.validity.patternMismatch) {
|
|
59
|
+
this.errorText = this.dataset.patternMsg || theme.t.errors.pattern;
|
|
60
|
+
} else if (this.input.validity.customError) {
|
|
61
|
+
this.errorText = this.input.validationMessage;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Validazione "equals": confronta con altro campo se richiesto
|
|
66
|
+
if (this.isValid && this.dataset.equals != undefined) {
|
|
67
|
+
const equalsInput = document.getElementById(this.dataset.equals);
|
|
68
|
+
if (!equalsInput) {
|
|
69
|
+
console.warn(`McInput: Element with ID ${this.dataset.equals} not found for equals validation`);
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
if (this.input.value != equalsInput.value) {
|
|
73
|
+
this.isValid = false;
|
|
74
|
+
this.errorText = theme.t.errors.equals;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Emette eventi custom in base alla validità
|
|
79
|
+
if (this.isValid) {
|
|
80
|
+
McShopify.customEvent(MCEVENTS.INPUT_VALID, {value: this.input.value}, this);
|
|
81
|
+
} else {
|
|
82
|
+
McShopify.customEvent(MCEVENTS.INPUT_ERROR, {message: this.errorText}, this);
|
|
83
|
+
}
|
|
84
|
+
this.showError(); // Mostra o nasconde il messaggio di errore
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Imposta errorText in base al tipo di input (email, url, ecc.)
|
|
88
|
+
validateType = () => {
|
|
89
|
+
switch (this.input.type) {
|
|
90
|
+
case 'email':
|
|
91
|
+
this.errorText = theme.t.errors.email;
|
|
92
|
+
break;
|
|
93
|
+
case 'url':
|
|
94
|
+
this.errorText = theme.t.errors.url;
|
|
95
|
+
break;
|
|
96
|
+
case 'number':
|
|
97
|
+
this.errorText = theme.t.errors.number;
|
|
98
|
+
break;
|
|
99
|
+
case 'integer':
|
|
100
|
+
this.errorText = theme.t.errors.integer;
|
|
101
|
+
break;
|
|
102
|
+
case 'date':
|
|
103
|
+
this.errorText = theme.t.errors.date;
|
|
104
|
+
break;
|
|
105
|
+
case 'time':
|
|
106
|
+
this.errorText = theme.t.errors.time;
|
|
107
|
+
break;
|
|
108
|
+
case 'datetime':
|
|
109
|
+
this.errorText = theme.t.errors.datetime;
|
|
110
|
+
break;
|
|
111
|
+
default:
|
|
112
|
+
this.errorText = theme.t.errors.pattern;
|
|
113
|
+
break;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Mostra o nasconde il messaggio di errore nell'elemento error
|
|
118
|
+
showError = () => {
|
|
119
|
+
this.isValid ? this.error.innerText = '' : this.error.innerText = this.errorText;
|
|
120
|
+
this.isValid ? this.classList.remove(McInput.ERROR_CLASS) : this.classList.add(McInput.ERROR_CLASS);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Se abilitato, invia automaticamente il form al change
|
|
124
|
+
autosubmit = () => {
|
|
125
|
+
if (this.dataset.autosubmit != undefined) {
|
|
126
|
+
this.input.addEventListener('change', () => {
|
|
127
|
+
const form = this.input.form;
|
|
128
|
+
if(!form) return;
|
|
129
|
+
McShopify.customEvent(MCEVENTS.FORM_AUTOSUBMIT, null, form);
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Esporta la classe McInput nel contesto globale e come modulo
|
|
136
|
+
window.McInput = McInput;
|
|
137
|
+
export default McInput;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
await loadComponent('./components/mc-element.js', false);
|
|
2
|
+
|
|
3
|
+
class McLoader extends McElement {
|
|
4
|
+
|
|
5
|
+
connectedCallback() {
|
|
6
|
+
if(this.dataset.global) {
|
|
7
|
+
window.onpageshow = () => {
|
|
8
|
+
this.deactivate();
|
|
9
|
+
}
|
|
10
|
+
window.onpagehide = () => {
|
|
11
|
+
this.activate();
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
if (!window.customElements.get("mc-loader")) {
|
|
17
|
+
window.customElements.define("mc-loader", McLoader);
|
|
18
|
+
McUtils.addCss(`https://cdn.jsdelivr.net/npm/teddy-frontend@${theme.version}/css/mc-loader.css`);
|
|
19
|
+
}
|
|
20
|
+
window.McLoader = McLoader;
|
|
21
|
+
export default McLoader;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
await loadComponent('./components/mc-element.js', false);
|
|
2
|
+
|
|
3
|
+
class McModal extends McElement {
|
|
4
|
+
delay; modal; scroll; scrollHandler; cansShow; days;
|
|
5
|
+
|
|
6
|
+
connectedCallback(){
|
|
7
|
+
this.init();
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
init = () => {
|
|
11
|
+
this.delay = isNaN(parseInt(this.dataset.delay)) ? 0 : parseInt(this.dataset.delay);
|
|
12
|
+
this.scroll = isNaN(parseInt(this.dataset.scroll)) ? 0 : parseInt(this.dataset.scroll);
|
|
13
|
+
this.days = isNaN(parseInt(this.dataset.remember)) ? 0 : parseInt(this.dataset.remember);
|
|
14
|
+
this.modal = bootstrap.Modal.getOrCreateInstance(this);
|
|
15
|
+
this.checkCanShow();
|
|
16
|
+
|
|
17
|
+
if(this.cansShow){
|
|
18
|
+
if(this.dataset.delay != undefined){
|
|
19
|
+
this.handleDelay();
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if(this.dataset.scroll != undefined){
|
|
23
|
+
this.scrollHandler = this.handleScroll.bind(this);
|
|
24
|
+
window.addEventListener('scroll', this.scrollHandler, false);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if(this.dataset.remember != undefined && this.days > 0){
|
|
28
|
+
this.addEventListener('hidden.bs.modal', () => this.remember());
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
remember = () => {
|
|
34
|
+
localStorage.setItem(this.id, Date.now() + this.days * 24 * 60 * 60 * 1000);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
checkCanShow = () => {
|
|
38
|
+
const stamp = parseInt(localStorage.getItem(this.id));
|
|
39
|
+
this.cansShow = false;
|
|
40
|
+
if(isNaN(stamp) || stamp < Date.now()){
|
|
41
|
+
this.cansShow = true;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
handleScroll = () => {
|
|
46
|
+
const scrollPosition = window.scrollY + window.innerHeight;
|
|
47
|
+
const pageHeight = document.documentElement.scrollHeight;
|
|
48
|
+
const scrollPercentage = this.scroll / 100;
|
|
49
|
+
if(scrollPosition / pageHeight > scrollPercentage){
|
|
50
|
+
this.show();
|
|
51
|
+
window.removeEventListener('scroll', this.scrollHandler, false);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
handleDelay = () => {
|
|
56
|
+
setTimeout(() => {
|
|
57
|
+
this.show();
|
|
58
|
+
}, this.delay);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
show = () => {
|
|
62
|
+
this.modal.show();
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
if (!window.customElements.get("mc-modal")) {
|
|
66
|
+
window.customElements.define("mc-modal", McModal);
|
|
67
|
+
}
|
|
68
|
+
window.McModal = McModal;
|
|
69
|
+
export default McModal;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
await loadComponent('./components/mc-element.js', false);
|
|
2
|
+
await loadComponent('./components/mc-btn.js', false);
|
|
3
|
+
await loadComponent('./res/mc-utils.js', false);
|
|
4
|
+
|
|
5
|
+
class McPasswordEye extends McBtn {
|
|
6
|
+
|
|
7
|
+
connectedCallback() {
|
|
8
|
+
|
|
9
|
+
if(!this.querySelector('.active')) { console.error('McPasswordEye: No active element found'); return; }
|
|
10
|
+
if(!this.querySelector('.inactive')) { console.error('McPasswordEye: No inactive element found'); return; }
|
|
11
|
+
|
|
12
|
+
this.target = this.closest('mc-input-password') || document.querySelector(this.dataset.inputPassword);
|
|
13
|
+
if (!this.target) { console.error('McPasswordEye: No McInputPassword found'); return; }
|
|
14
|
+
|
|
15
|
+
this.init();
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
}
|
|
19
|
+
if (!window.customElements.get("mc-password-eye")) {
|
|
20
|
+
window.customElements.define("mc-password-eye", McPasswordEye);
|
|
21
|
+
McUtils.addCss(`https://cdn.jsdelivr.net/npm/teddy-frontend@${theme.version}/css/mc-password-eye.css`);
|
|
22
|
+
}
|
|
23
|
+
window.McPasswordEye = McPasswordEye;
|
|
24
|
+
export default McPasswordEye;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
await loadComponent('./components/mc-element.js', false);
|
|
2
|
+
await loadComponent('./components/mc-input-password.js', false);
|
|
3
|
+
|
|
4
|
+
class McPasswordTips extends McElement {
|
|
5
|
+
static classes = {
|
|
6
|
+
valid: 'valid',
|
|
7
|
+
allValid: 'alert-success',
|
|
8
|
+
someInvalid: 'alert-warning'
|
|
9
|
+
};
|
|
10
|
+
points;
|
|
11
|
+
|
|
12
|
+
connectedCallback() {
|
|
13
|
+
this.points = this.querySelectorAll("[data-pattern]");
|
|
14
|
+
if (this.points.length === 0) { console.error("McPasswordTips: No points found with data-pattern attribute."); return; }
|
|
15
|
+
|
|
16
|
+
this.inputPassword = this.closest("mc-input-password") || document.querySelector(this.dataset.inputPassword);
|
|
17
|
+
if (!this.inputPassword) { console.error("McPasswordTips: No McInputPassword found"); return; }
|
|
18
|
+
|
|
19
|
+
this.inputPassword.input.addEventListener("focus", this.activate.bind(this));
|
|
20
|
+
this.inputPassword.input.addEventListener("blur", this.deactivate.bind(this));
|
|
21
|
+
this.inputPassword.input.addEventListener("input", () => {
|
|
22
|
+
this.checkPoints(this.inputPassword.input.value);
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
checkPoints = (value) => {
|
|
27
|
+
const validClass = this.dataset.validClass || McPasswordTips.classes.valid;
|
|
28
|
+
this.points.forEach(point => {
|
|
29
|
+
let pattern = new RegExp(point.dataset.pattern);
|
|
30
|
+
if (pattern.test(value)) {
|
|
31
|
+
point.classList.add(validClass);
|
|
32
|
+
} else {
|
|
33
|
+
point.classList.remove(validClass);
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
this.setValid();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
setValid = () => {
|
|
40
|
+
const allValidClasses = this.dataset.allValidClasses?.split(' ') || McPasswordTips.classes.allValid?.split(' ') || [];
|
|
41
|
+
const validClass = this.dataset.validClass || McPasswordTips.classes.valid;
|
|
42
|
+
const someInvalidClasses = this.dataset.someInvalidClasses?.split(' ') || McPasswordTips.classes.someInvalid?.split(' ') || [];
|
|
43
|
+
|
|
44
|
+
const valid = this.querySelectorAll(`[data-pattern].${validClass}`).length;
|
|
45
|
+
const total = this.points.length;
|
|
46
|
+
if(valid === total){
|
|
47
|
+
this.classList.add(...allValidClasses);
|
|
48
|
+
this.classList.remove(...someInvalidClasses);
|
|
49
|
+
} else {
|
|
50
|
+
this.classList.add(...someInvalidClasses);
|
|
51
|
+
this.classList.remove(...allValidClasses);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
if (!window.customElements.get("mc-password-tips")) {
|
|
56
|
+
window.customElements.define("mc-password-tips", McPasswordTips);
|
|
57
|
+
McUtils.addCss(`https://cdn.jsdelivr.net/npm/teddy-frontend@${theme.version}/css/mc-password-tips.css`);
|
|
58
|
+
}
|
|
59
|
+
window.McPasswordTips = McPasswordTips;
|
|
60
|
+
export default McPasswordTips;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
await loadComponent('./components/mc-element.js', false);
|
|
2
|
+
|
|
3
|
+
class McQrcode extends McElement {
|
|
4
|
+
|
|
5
|
+
connectedCallback() {
|
|
6
|
+
const observer = new IntersectionObserver(
|
|
7
|
+
(entries, obs) => {
|
|
8
|
+
entries.forEach(entry => {
|
|
9
|
+
if (entry.isIntersecting) {
|
|
10
|
+
// L'elemento è nella viewport
|
|
11
|
+
this.init();
|
|
12
|
+
obs.unobserve(this); // Osserva solo la prima volta
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
},
|
|
16
|
+
{ threshold: 0.1 }
|
|
17
|
+
);
|
|
18
|
+
observer.observe(this);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
init = async () => {
|
|
22
|
+
//await import(theme.qrcode);
|
|
23
|
+
if(!QRCode) {
|
|
24
|
+
console.error('QRCode library not loaded');
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
new QRCode(this, {
|
|
28
|
+
text: this.dataset.text,
|
|
29
|
+
width: parseInt(this.dataset.width) || 128,
|
|
30
|
+
height: parseInt(this.dataset.height) || 128,
|
|
31
|
+
colorDark : this.dataset.colorDark || "#000000",
|
|
32
|
+
colorLight : this.dataset.colorLight || "#ffffff",
|
|
33
|
+
correctLevel : QRCode.CorrectLevel.H
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (!customElements.get('mc-qrcode')) {
|
|
39
|
+
customElements.define('mc-qrcode', McQrcode);
|
|
40
|
+
}
|
|
41
|
+
window.McQrcode = McQrcode;
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import 'https://cdn.jsdelivr.net/npm/nouislider@15.8.1';
|
|
2
|
+
await loadComponent('./components/mc-element.js', false);
|
|
3
|
+
await loadComponent('./res/mc-utils.js', false);
|
|
4
|
+
|
|
5
|
+
class McRange extends McElement {
|
|
6
|
+
values;
|
|
7
|
+
|
|
8
|
+
connectedCallback() {
|
|
9
|
+
this.getValues();
|
|
10
|
+
this.render();
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// renderizzo lo slider
|
|
14
|
+
render = () => {
|
|
15
|
+
if(this.values?.length){
|
|
16
|
+
noUiSlider.create(this, {
|
|
17
|
+
start: this.values,
|
|
18
|
+
connect: true,
|
|
19
|
+
range: {
|
|
20
|
+
'min': parseInt(this.dataset.min),
|
|
21
|
+
'max': parseInt(this.dataset.max)
|
|
22
|
+
},
|
|
23
|
+
step: parseInt(this.dataset.step) || 1
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
this.noUiSlider.on('update', (values) => {
|
|
27
|
+
this.setValues(values);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
this.noUiSlider.on('change', (values) => {
|
|
31
|
+
this.setValues(values);
|
|
32
|
+
McShopify.customEvent('change', this.getPairs(), this);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
this.inputEvents();
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// ottiene un oggetto name:value
|
|
40
|
+
getPairs = () => {
|
|
41
|
+
return {
|
|
42
|
+
items: this.dataset.inputSelectors?.split(',').map(selector => {
|
|
43
|
+
const input = document.querySelector(selector);
|
|
44
|
+
return { name: input.name, value: input.value };
|
|
45
|
+
})
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// fa controllare lo slider dalle sue input
|
|
50
|
+
inputEvents = () => {
|
|
51
|
+
const inputs = this.dataset.inputSelectors?.split(',').map(selector => document.querySelector(selector));
|
|
52
|
+
if(inputs !== undefined){
|
|
53
|
+
inputs.forEach((input, index) => {
|
|
54
|
+
input.addEventListener('input', (e) => {
|
|
55
|
+
this.values[index] = parseInt(e.target.value);
|
|
56
|
+
this.noUiSlider.set(this.values);
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// ottengo i valori
|
|
63
|
+
getValues = () => {
|
|
64
|
+
this.values = this.dataset.values?.split(',').map(value => parseInt(value));
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// setto i valori
|
|
68
|
+
setValues = (values) => {
|
|
69
|
+
this.values = values;
|
|
70
|
+
this.renderValues();
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// renderizzo i valori
|
|
74
|
+
renderValues = () => {
|
|
75
|
+
const labels = this.dataset.labels?.split(',').map(label => document.querySelector(label));
|
|
76
|
+
const inputs = this.dataset.inputSelectors?.split(',').map(selector => document.querySelector(selector));
|
|
77
|
+
if(labels !== undefined){
|
|
78
|
+
labels.forEach((label, index) => {
|
|
79
|
+
label.innerHTML = this.formatLabel(this.values[index]);
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
if(inputs !== undefined){
|
|
83
|
+
inputs.forEach((input, index) => {
|
|
84
|
+
input.value = this.formatInput(this.values[index]);
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// formatto i valori in base al formato, se è money uso utils.money
|
|
90
|
+
formatLabel = (value) => {
|
|
91
|
+
const format = this.dataset.format || '{label}';
|
|
92
|
+
if(format == 'money')
|
|
93
|
+
return McUtils.money(value*100);
|
|
94
|
+
else
|
|
95
|
+
return format.replaceAll('{label}', value);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// formatta i valori per le input
|
|
99
|
+
formatInput = (value) => {
|
|
100
|
+
return parseInt(value);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
if (!window.customElements.get("mc-range")) {
|
|
104
|
+
window.customElements.define("mc-range", McRange);
|
|
105
|
+
McUtils.addCss(`/cdn/shop/t/32/assets/nouislider.min.css`);
|
|
106
|
+
}
|
|
107
|
+
window.McRange = McRange;
|
|
108
|
+
export default McRange;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import '../res/mc-events.js';
|
|
2
|
+
await loadComponent('./components/mc-element.js', false);
|
|
3
|
+
|
|
4
|
+
class McReadMore extends McElement {
|
|
5
|
+
expanded; expandible; link; text; observer;
|
|
6
|
+
|
|
7
|
+
connectedCallback(){
|
|
8
|
+
this.text = this.querySelector(':scope > div');
|
|
9
|
+
if(!this.text){ console.error('McReadMore: You need to provide a div element'); return; }
|
|
10
|
+
if(!this.dataset.moreText){ console.error('McReadMore: You need to provide a data-more-text attribute'); return; }
|
|
11
|
+
if(!this.dataset.lessText) { console.error('McReadMore: You need to provide a data-less-text attribute'); return; }
|
|
12
|
+
|
|
13
|
+
this.checkExpandible();
|
|
14
|
+
this.observer = new ResizeObserver(() => this.checkExpandible());
|
|
15
|
+
this.observer.observe(this);
|
|
16
|
+
|
|
17
|
+
this.addEventListener(MCEVENTS.EL_ACTIVATED, this.setText.bind(this));
|
|
18
|
+
this.addEventListener(MCEVENTS.EL_DEACTIVATED, this.setText.bind(this));
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
checkExpandible = () => {
|
|
22
|
+
if(this.offsetParent !== null){
|
|
23
|
+
this.expanded = false;
|
|
24
|
+
this.expandible = this.text.scrollHeight > this.text.clientHeight;
|
|
25
|
+
if(this.expandible){
|
|
26
|
+
this.addLink();
|
|
27
|
+
}
|
|
28
|
+
this.observer.disconnect();
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
addLink = () => {
|
|
33
|
+
const classes = this.dataset.classes?.split(' ') || ["read-more-link"];
|
|
34
|
+
this.link = document.createElement('mc-btn');
|
|
35
|
+
this.link.setAttribute('data-target', this.getSelector());
|
|
36
|
+
this.link.innerText = this.dataset.moreText;
|
|
37
|
+
this.link.classList.add(...classes);
|
|
38
|
+
this.appendChild(this.link);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
setText = () => {
|
|
42
|
+
if(this.expandible && this.link){
|
|
43
|
+
if(this.isActive()){
|
|
44
|
+
this.link.innerText = this.dataset.lessText;
|
|
45
|
+
} else {
|
|
46
|
+
this.link.innerText = this.dataset.moreText;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
if (!window.customElements.get("mc-read-more")) {
|
|
52
|
+
window.customElements.define("mc-read-more", McReadMore);
|
|
53
|
+
McUtils.addCss(`https://cdn.jsdelivr.net/npm/teddy-frontend@${theme.version}/css/mc-read-more.css`);
|
|
54
|
+
}
|
|
55
|
+
window.McReadMore = McReadMore;
|
|
56
|
+
export default McReadMore;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// Questo componente `McRecommended` estende la classe base `McElement` e serve per mostrare una lista di prodotti raccomandati (ad esempio prodotti correlati o complementari) in una pagina prodotto.
|
|
2
|
+
// Utilizza le API di Shopify per recuperare i prodotti consigliati in base al prodotto corrente.
|
|
3
|
+
// Richiede che vengano specificati alcuni data attributes sull'elemento HTML:
|
|
4
|
+
// - data-product-id: ID del prodotto di riferimento (obbligatorio)
|
|
5
|
+
// - data-section-id: ID della sezione Shopify da aggiornare (obbligatorio)
|
|
6
|
+
// - data-limit: numero massimo di prodotti da mostrare (opzionale, default 10)
|
|
7
|
+
// - data-intent: tipo di raccomandazione (opzionale, valori possibili: 'related' o 'complementary')
|
|
8
|
+
|
|
9
|
+
// Non sono richiesti elementi HTML interni specifici: il componente aggiorna se stesso con i prodotti raccomandati ricevuti dalla chiamata API.
|
|
10
|
+
|
|
11
|
+
await loadComponent('./components/mc-element.js', false);
|
|
12
|
+
await loadComponent('./res/mc-utils.js', false);
|
|
13
|
+
await loadComponent('./res/mc-shopify.js', false);
|
|
14
|
+
|
|
15
|
+
class McRecommended extends McElement {
|
|
16
|
+
|
|
17
|
+
// Metodo chiamato automaticamente quando l'elemento viene aggiunto al DOM
|
|
18
|
+
connectedCallback() {
|
|
19
|
+
this.loadProducts(); // Carica i prodotti raccomandati
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// Recupera i prodotti raccomandati tramite l'API Shopify e aggiorna il contenuto del componente
|
|
23
|
+
loadProducts = () => {
|
|
24
|
+
if(!this.dataset.productId || !this.dataset.sectionId) { console.error('ID del prodotto o ID della sezione non forniti.'); return;}
|
|
25
|
+
|
|
26
|
+
McShopify.getRecommendations({
|
|
27
|
+
product_id: this.dataset.productId, // ID del prodotto corrente
|
|
28
|
+
section_id: this.dataset.sectionId, // ID della sezione corrente
|
|
29
|
+
limit: parseInt(this.dataset.limit) || 10, // Numero massimo di prodotti da restituire
|
|
30
|
+
intent: this.dataset.intent || 'related', // Intento della raccomandazione (related | complementary)
|
|
31
|
+
onSuccess: (response) => {
|
|
32
|
+
McUtils.reloadElement(response, this, this.getSelector()); // Renderizza i prodotti raccomandati
|
|
33
|
+
},
|
|
34
|
+
onError: (error) => {
|
|
35
|
+
console.error('Errore nel caricamento dei prodotti raccomandati:', error);
|
|
36
|
+
this.remove(); // Rimuove l'elemento in caso di errore
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Registra il componente custom se non già presente
|
|
44
|
+
if(!customElements.get('mc-recommended')) {
|
|
45
|
+
customElements.define('mc-recommended', McRecommended);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Espone la classe globalmente e come modulo
|
|
49
|
+
window.McRecommended = McRecommended;
|
|
50
|
+
export default McRecommended;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
await loadComponent('./components/mc-element.js', false);
|
|
2
|
+
|
|
3
|
+
class McReferrer extends McElement {
|
|
4
|
+
|
|
5
|
+
// al click va su document.referrer
|
|
6
|
+
connectedCallback() {
|
|
7
|
+
if(window.location.href != document.referrer){
|
|
8
|
+
this.addEventListener('click', () => {
|
|
9
|
+
window.location.href = document.referrer;
|
|
10
|
+
});
|
|
11
|
+
} else {
|
|
12
|
+
this.remove();
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
if (!window.customElements.get("mc-referrer")) {
|
|
17
|
+
window.customElements.define("mc-referrer", McReferrer);
|
|
18
|
+
}
|
|
19
|
+
window.McReferrer = McReferrer;
|
|
20
|
+
export default McReferrer;
|