@magic-spells/cart-progress-bar 0.2.1 → 2.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 +89 -32
- package/dist/cart-progress-bar.css +15 -36
- package/dist/cart-progress-bar.esm.js +197 -273
- package/dist/cart-progress-bar.min.css +2 -1
- package/dist/cart-progress-bar.min.js +1 -1
- package/package.json +19 -26
- package/dist/cart-progress-bar.cjs.js +0 -333
- package/dist/cart-progress-bar.cjs.js.map +0 -1
- package/dist/cart-progress-bar.esm.js.map +0 -1
- package/dist/cart-progress-bar.js +0 -339
- package/dist/cart-progress-bar.js.map +0 -1
- package/dist/cart-progress-bar.scss +0 -124
- package/src/cart-progress-bar.js +0 -332
- package/src/cart-progress-bar.scss +0 -124
|
@@ -1,339 +0,0 @@
|
|
|
1
|
-
(function (global, factory) {
|
|
2
|
-
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
|
|
3
|
-
typeof define === 'function' && define.amd ? define(['exports'], factory) :
|
|
4
|
-
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.CartProgressBar = {}));
|
|
5
|
-
})(this, (function (exports) { 'use strict';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* ProgressBar helper class for the visual progress bar element
|
|
9
|
-
*/
|
|
10
|
-
class ProgressBar extends HTMLElement {
|
|
11
|
-
constructor() {
|
|
12
|
-
super();
|
|
13
|
-
this.#setupProgressBar();
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
#setupProgressBar() {
|
|
17
|
-
this.setAttribute('role', 'progressbar');
|
|
18
|
-
this.setAttribute('aria-valuemin', '0');
|
|
19
|
-
this.setAttribute('aria-valuemax', '100');
|
|
20
|
-
this.setAttribute('aria-valuenow', '0');
|
|
21
|
-
|
|
22
|
-
// Create the visual progress bar
|
|
23
|
-
this.innerHTML = '<div class="progress-bar-fill"></div>';
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
setPercent(percent) {
|
|
27
|
-
const clampedPercent = Math.max(0, Math.min(100, percent));
|
|
28
|
-
this.style.setProperty('--cart-progress-percent', `${clampedPercent}%`);
|
|
29
|
-
this.setAttribute('aria-valuenow', clampedPercent);
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// Define ProgressBar custom element immediately so it's available for CartProgressBar
|
|
34
|
-
customElements.define('progress-bar', ProgressBar);
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* CartProgressBar main component
|
|
38
|
-
*/
|
|
39
|
-
class CartProgressBar extends HTMLElement {
|
|
40
|
-
// Private fields
|
|
41
|
-
#minAmount = 0;
|
|
42
|
-
#currentAmount = 0;
|
|
43
|
-
#progressPercent = 0;
|
|
44
|
-
#originalAboveMessage = '';
|
|
45
|
-
#originalBelowMessage = '';
|
|
46
|
-
#progressBar = null;
|
|
47
|
-
#messageElement = null;
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Define which attributes should be observed for changes
|
|
51
|
-
*/
|
|
52
|
-
static get observedAttributes() {
|
|
53
|
-
return ['threshold', 'current', 'message-above', 'message-below'];
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
constructor() {
|
|
57
|
-
super();
|
|
58
|
-
this.#init();
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
#init() {
|
|
62
|
-
// Read initial attributes
|
|
63
|
-
this.#minAmount = parseFloat(this.getAttribute('threshold')) || 0;
|
|
64
|
-
this.#currentAmount = parseFloat(this.getAttribute('current')) || 0;
|
|
65
|
-
|
|
66
|
-
// Store original message templates
|
|
67
|
-
this.#originalAboveMessage = this.getAttribute('message-above') || '';
|
|
68
|
-
this.#originalBelowMessage = this.getAttribute('message-below') || '';
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
async connectedCallback() {
|
|
72
|
-
// ensure the child custom element has been registered
|
|
73
|
-
await customElements.whenDefined('progress-bar');
|
|
74
|
-
|
|
75
|
-
if (!customElements.get('progress-bar')) {
|
|
76
|
-
throw new Error('<progress-bar> must be registered before <cart-progress-bar> runs');
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
this.#render();
|
|
80
|
-
this.#updateProgress();
|
|
81
|
-
this.#attachListeners();
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
attributeChangedCallback(name, oldValue, newValue) {
|
|
85
|
-
if (oldValue === newValue) return;
|
|
86
|
-
|
|
87
|
-
switch (name) {
|
|
88
|
-
case 'threshold':
|
|
89
|
-
this.#minAmount = parseFloat(newValue) || 0;
|
|
90
|
-
this.#updateProgress();
|
|
91
|
-
break;
|
|
92
|
-
case 'current':
|
|
93
|
-
this.#currentAmount = parseFloat(newValue) || 0;
|
|
94
|
-
this.#updateProgress();
|
|
95
|
-
break;
|
|
96
|
-
case 'message-above':
|
|
97
|
-
this.#originalAboveMessage = newValue || '';
|
|
98
|
-
this.#updateMessages();
|
|
99
|
-
break;
|
|
100
|
-
case 'message-below':
|
|
101
|
-
this.#originalBelowMessage = newValue || '';
|
|
102
|
-
this.#updateMessages();
|
|
103
|
-
break;
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
#render() {
|
|
108
|
-
// Find or create the message element
|
|
109
|
-
this.#messageElement =
|
|
110
|
-
this.querySelector('[data-content-cart-progress-message]') ||
|
|
111
|
-
this.querySelector('p[data-content-cart-progress-message]');
|
|
112
|
-
|
|
113
|
-
// Find existing progress bar (user can add their own)
|
|
114
|
-
this.#progressBar = this.querySelector('progress-bar');
|
|
115
|
-
|
|
116
|
-
// Create message element if it doesn't exist but we have message templates
|
|
117
|
-
if (!this.#messageElement && (this.#originalAboveMessage || this.#originalBelowMessage)) {
|
|
118
|
-
this.#messageElement = document.createElement('p');
|
|
119
|
-
this.#messageElement.setAttribute('data-content-cart-progress-message', '');
|
|
120
|
-
this.appendChild(this.#messageElement);
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
// Create progress bar if it doesn't exist - add it at the end (below text message)
|
|
124
|
-
if (!this.#progressBar) {
|
|
125
|
-
// Ensure progress-bar is defined before creating
|
|
126
|
-
if (customElements.get('progress-bar')) {
|
|
127
|
-
this.#progressBar = document.createElement('progress-bar');
|
|
128
|
-
this.appendChild(this.#progressBar);
|
|
129
|
-
} else {
|
|
130
|
-
// Fallback: wait for definition
|
|
131
|
-
customElements.whenDefined('progress-bar').then(() => {
|
|
132
|
-
if (!this.#progressBar) {
|
|
133
|
-
this.#progressBar = document.createElement('progress-bar');
|
|
134
|
-
this.appendChild(this.#progressBar);
|
|
135
|
-
this.#updateProgress(); // Update progress after creating
|
|
136
|
-
}
|
|
137
|
-
});
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
#updateProgress() {
|
|
143
|
-
if (this.#minAmount === 0) {
|
|
144
|
-
this.#progressPercent = 100;
|
|
145
|
-
} else {
|
|
146
|
-
this.#progressPercent = Math.min(100, (this.#currentAmount / this.#minAmount) * 100);
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
// Update progress bar
|
|
150
|
-
if (this.#progressBar) {
|
|
151
|
-
this.#progressBar.setPercent(this.#progressPercent);
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
// Update messages
|
|
155
|
-
this.#updateMessages();
|
|
156
|
-
|
|
157
|
-
// Update component state
|
|
158
|
-
this.#updateComponentState();
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
#attachListeners() {
|
|
162
|
-
// Find the nearest cart-panel component
|
|
163
|
-
const cartDialog = this.closest('cart-dialog');
|
|
164
|
-
|
|
165
|
-
if (cartDialog) {
|
|
166
|
-
// Listen for cart data changes
|
|
167
|
-
cartDialog.addEventListener('cart-dialog:data-changed', (event) => {
|
|
168
|
-
this.#handleCartDataChange(event);
|
|
169
|
-
});
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
#handleCartDataChange(event) {
|
|
174
|
-
const updatedCart = event.detail;
|
|
175
|
-
|
|
176
|
-
if (updatedCart) {
|
|
177
|
-
// Use calculated_subtotal if available (handles _ignore_price_in_subtotal logic)
|
|
178
|
-
// Otherwise fall back to total_price for backwards compatibility
|
|
179
|
-
let currentAmount = 0;
|
|
180
|
-
|
|
181
|
-
if (typeof updatedCart.calculated_subtotal !== 'undefined') {
|
|
182
|
-
// calculated_subtotal is already in dollars, no conversion needed
|
|
183
|
-
currentAmount = updatedCart.calculated_subtotal / 100;
|
|
184
|
-
} else if (typeof updatedCart.total_price !== 'undefined') {
|
|
185
|
-
// Convert from cents to dollars if needed (Shopify typically returns cents)
|
|
186
|
-
currentAmount = updatedCart.total_price / 100;
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
this.setCurrentAmount(currentAmount);
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
#updateMessages() {
|
|
194
|
-
const isComplete = this.#currentAmount >= this.#minAmount;
|
|
195
|
-
const remainingAmount = Math.max(0, this.#minAmount - this.#currentAmount);
|
|
196
|
-
|
|
197
|
-
// Format amount with minimal formatting
|
|
198
|
-
const formattedAmount = remainingAmount.toFixed(2).replace('.00', '');
|
|
199
|
-
|
|
200
|
-
// Update the single message element
|
|
201
|
-
if (this.#messageElement) {
|
|
202
|
-
let messageTemplate;
|
|
203
|
-
|
|
204
|
-
if (isComplete && this.#originalAboveMessage) {
|
|
205
|
-
// Show success message when complete
|
|
206
|
-
messageTemplate = this.#originalAboveMessage;
|
|
207
|
-
} else if (!isComplete) {
|
|
208
|
-
// Show progress message when incomplete
|
|
209
|
-
messageTemplate = this.#originalBelowMessage || this.#originalAboveMessage;
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
if (messageTemplate) {
|
|
213
|
-
// Support multiple placeholder formats: {amount}, { amount }, [amount]
|
|
214
|
-
const message = messageTemplate
|
|
215
|
-
.replace(/\{\s*amount\s*\}/g, formattedAmount)
|
|
216
|
-
.replace(/\[\s*amount\s*\]/g, formattedAmount);
|
|
217
|
-
this.#messageElement.textContent = message;
|
|
218
|
-
this.#messageElement.style.display = 'block';
|
|
219
|
-
} else {
|
|
220
|
-
// Hide message if no template available for current state
|
|
221
|
-
this.#messageElement.style.display = 'none';
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
#updateComponentState() {
|
|
227
|
-
const isComplete = this.#currentAmount >= this.#minAmount;
|
|
228
|
-
this.setAttribute('complete', isComplete.toString());
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
/**
|
|
233
|
-
* Public API: Set the progress percentage directly
|
|
234
|
-
* @param {number} percent - Progress percentage (0-100)
|
|
235
|
-
*/
|
|
236
|
-
setPercent(percent) {
|
|
237
|
-
const clampedPercent = Math.max(0, Math.min(100, percent));
|
|
238
|
-
this.#progressPercent = clampedPercent;
|
|
239
|
-
|
|
240
|
-
if (this.#progressBar) {
|
|
241
|
-
this.#progressBar.setPercent(clampedPercent);
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
// Calculate current amount based on percentage
|
|
245
|
-
this.#currentAmount = (clampedPercent / 100) * this.#minAmount;
|
|
246
|
-
this.setAttribute('current', this.#currentAmount.toString());
|
|
247
|
-
|
|
248
|
-
this.#updateMessages();
|
|
249
|
-
this.#updateComponentState();
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
/**
|
|
253
|
-
* Public API: Set the current cart amount
|
|
254
|
-
* @param {number} amount - Current cart amount
|
|
255
|
-
*/
|
|
256
|
-
setCurrentAmount(amount) {
|
|
257
|
-
this.#currentAmount = parseFloat(amount) || 0;
|
|
258
|
-
this.setAttribute('current', this.#currentAmount.toString());
|
|
259
|
-
this.#updateProgress();
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
/**
|
|
263
|
-
* Public API: Set the threshold amount for free shipping
|
|
264
|
-
* @param {number} amount - Threshold amount for free shipping
|
|
265
|
-
*/
|
|
266
|
-
setThresholdAmount(amount) {
|
|
267
|
-
this.#minAmount = parseFloat(amount) || 0;
|
|
268
|
-
this.setAttribute('threshold', this.#minAmount.toString());
|
|
269
|
-
this.#updateProgress();
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
/**
|
|
273
|
-
* Public API: Set the minimum amount for free shipping (deprecated - use setThresholdAmount)
|
|
274
|
-
* @param {number} amount - Minimum amount threshold
|
|
275
|
-
* @deprecated Use setThresholdAmount instead
|
|
276
|
-
*/
|
|
277
|
-
setMinAmount(amount) {
|
|
278
|
-
this.setThresholdAmount(amount);
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
/**
|
|
282
|
-
* Public API: Get current progress information
|
|
283
|
-
*/
|
|
284
|
-
getProgress() {
|
|
285
|
-
return {
|
|
286
|
-
currentAmount: this.#currentAmount,
|
|
287
|
-
thresholdAmount: this.#minAmount,
|
|
288
|
-
minAmount: this.#minAmount, // backwards compatibility
|
|
289
|
-
remainingAmount: Math.max(0, this.#minAmount - this.#currentAmount),
|
|
290
|
-
percent: this.#progressPercent,
|
|
291
|
-
isComplete: this.#currentAmount >= this.#minAmount,
|
|
292
|
-
};
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
/**
|
|
296
|
-
* Public API: Update message templates
|
|
297
|
-
* @param {string} aboveMessage - Message template for above the bar
|
|
298
|
-
* @param {string} belowMessage - Message template for below the bar
|
|
299
|
-
*/
|
|
300
|
-
setMessages(aboveMessage = null, belowMessage = null) {
|
|
301
|
-
if (aboveMessage !== null) {
|
|
302
|
-
this.#originalAboveMessage = aboveMessage;
|
|
303
|
-
this.setAttribute('message-above', aboveMessage);
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
if (belowMessage !== null) {
|
|
307
|
-
this.#originalBelowMessage = belowMessage;
|
|
308
|
-
this.setAttribute('message-below', belowMessage);
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
this.#updateMessages();
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
// Getters
|
|
315
|
-
get currentAmount() {
|
|
316
|
-
return this.#currentAmount;
|
|
317
|
-
}
|
|
318
|
-
get thresholdAmount() {
|
|
319
|
-
return this.#minAmount;
|
|
320
|
-
}
|
|
321
|
-
get minAmount() {
|
|
322
|
-
return this.#minAmount;
|
|
323
|
-
} // backwards compatibility
|
|
324
|
-
get percent() {
|
|
325
|
-
return this.#progressPercent;
|
|
326
|
-
}
|
|
327
|
-
get isComplete() {
|
|
328
|
-
return this.#currentAmount >= this.#minAmount;
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
// Define CartProgressBar custom element
|
|
333
|
-
customElements.define('cart-progress-bar', CartProgressBar);
|
|
334
|
-
|
|
335
|
-
exports.CartProgressBar = CartProgressBar;
|
|
336
|
-
exports.ProgressBar = ProgressBar;
|
|
337
|
-
|
|
338
|
-
}));
|
|
339
|
-
//# sourceMappingURL=cart-progress-bar.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cart-progress-bar.js","sources":["../src/cart-progress-bar.js"],"sourcesContent":["import './cart-progress-bar.scss';\n\n/**\n * ProgressBar helper class for the visual progress bar element\n */\nclass ProgressBar extends HTMLElement {\n\tconstructor() {\n\t\tsuper();\n\t\tthis.#setupProgressBar();\n\t}\n\n\t#setupProgressBar() {\n\t\tthis.setAttribute('role', 'progressbar');\n\t\tthis.setAttribute('aria-valuemin', '0');\n\t\tthis.setAttribute('aria-valuemax', '100');\n\t\tthis.setAttribute('aria-valuenow', '0');\n\n\t\t// Create the visual progress bar\n\t\tthis.innerHTML = '<div class=\"progress-bar-fill\"></div>';\n\t}\n\n\tsetPercent(percent) {\n\t\tconst clampedPercent = Math.max(0, Math.min(100, percent));\n\t\tthis.style.setProperty('--cart-progress-percent', `${clampedPercent}%`);\n\t\tthis.setAttribute('aria-valuenow', clampedPercent);\n\t}\n}\n\n// Define ProgressBar custom element immediately so it's available for CartProgressBar\ncustomElements.define('progress-bar', ProgressBar);\n\n/**\n * CartProgressBar main component\n */\nclass CartProgressBar extends HTMLElement {\n\t// Private fields\n\t#minAmount = 0;\n\t#currentAmount = 0;\n\t#progressPercent = 0;\n\t#originalAboveMessage = '';\n\t#originalBelowMessage = '';\n\t#progressBar = null;\n\t#messageElement = null;\n\n\t/**\n\t * Define which attributes should be observed for changes\n\t */\n\tstatic get observedAttributes() {\n\t\treturn ['threshold', 'current', 'message-above', 'message-below'];\n\t}\n\n\tconstructor() {\n\t\tsuper();\n\t\tthis.#init();\n\t}\n\n\t#init() {\n\t\t// Read initial attributes\n\t\tthis.#minAmount = parseFloat(this.getAttribute('threshold')) || 0;\n\t\tthis.#currentAmount = parseFloat(this.getAttribute('current')) || 0;\n\n\t\t// Store original message templates\n\t\tthis.#originalAboveMessage = this.getAttribute('message-above') || '';\n\t\tthis.#originalBelowMessage = this.getAttribute('message-below') || '';\n\t}\n\n\tasync connectedCallback() {\n\t\t// ensure the child custom element has been registered\n\t\tawait customElements.whenDefined('progress-bar');\n\n\t\tif (!customElements.get('progress-bar')) {\n\t\t\tthrow new Error('<progress-bar> must be registered before <cart-progress-bar> runs');\n\t\t}\n\n\t\tthis.#render();\n\t\tthis.#updateProgress();\n\t\tthis.#attachListeners();\n\t}\n\n\tattributeChangedCallback(name, oldValue, newValue) {\n\t\tif (oldValue === newValue) return;\n\n\t\tswitch (name) {\n\t\t\tcase 'threshold':\n\t\t\t\tthis.#minAmount = parseFloat(newValue) || 0;\n\t\t\t\tthis.#updateProgress();\n\t\t\t\tbreak;\n\t\t\tcase 'current':\n\t\t\t\tthis.#currentAmount = parseFloat(newValue) || 0;\n\t\t\t\tthis.#updateProgress();\n\t\t\t\tbreak;\n\t\t\tcase 'message-above':\n\t\t\t\tthis.#originalAboveMessage = newValue || '';\n\t\t\t\tthis.#updateMessages();\n\t\t\t\tbreak;\n\t\t\tcase 'message-below':\n\t\t\t\tthis.#originalBelowMessage = newValue || '';\n\t\t\t\tthis.#updateMessages();\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\t#render() {\n\t\t// Find or create the message element\n\t\tthis.#messageElement =\n\t\t\tthis.querySelector('[data-content-cart-progress-message]') ||\n\t\t\tthis.querySelector('p[data-content-cart-progress-message]');\n\n\t\t// Find existing progress bar (user can add their own)\n\t\tthis.#progressBar = this.querySelector('progress-bar');\n\n\t\t// Create message element if it doesn't exist but we have message templates\n\t\tif (!this.#messageElement && (this.#originalAboveMessage || this.#originalBelowMessage)) {\n\t\t\tthis.#messageElement = document.createElement('p');\n\t\t\tthis.#messageElement.setAttribute('data-content-cart-progress-message', '');\n\t\t\tthis.appendChild(this.#messageElement);\n\t\t}\n\n\t\t// Create progress bar if it doesn't exist - add it at the end (below text message)\n\t\tif (!this.#progressBar) {\n\t\t\t// Ensure progress-bar is defined before creating\n\t\t\tif (customElements.get('progress-bar')) {\n\t\t\t\tthis.#progressBar = document.createElement('progress-bar');\n\t\t\t\tthis.appendChild(this.#progressBar);\n\t\t\t} else {\n\t\t\t\t// Fallback: wait for definition\n\t\t\t\tcustomElements.whenDefined('progress-bar').then(() => {\n\t\t\t\t\tif (!this.#progressBar) {\n\t\t\t\t\t\tthis.#progressBar = document.createElement('progress-bar');\n\t\t\t\t\t\tthis.appendChild(this.#progressBar);\n\t\t\t\t\t\tthis.#updateProgress(); // Update progress after creating\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\t#updateProgress() {\n\t\tif (this.#minAmount === 0) {\n\t\t\tthis.#progressPercent = 100;\n\t\t} else {\n\t\t\tthis.#progressPercent = Math.min(100, (this.#currentAmount / this.#minAmount) * 100);\n\t\t}\n\n\t\t// Update progress bar\n\t\tif (this.#progressBar) {\n\t\t\tthis.#progressBar.setPercent(this.#progressPercent);\n\t\t}\n\n\t\t// Update messages\n\t\tthis.#updateMessages();\n\n\t\t// Update component state\n\t\tthis.#updateComponentState();\n\t}\n\n\t#attachListeners() {\n\t\t// Find the nearest cart-panel component\n\t\tconst cartDialog = this.closest('cart-dialog');\n\n\t\tif (cartDialog) {\n\t\t\t// Listen for cart data changes\n\t\t\tcartDialog.addEventListener('cart-dialog:data-changed', (event) => {\n\t\t\t\tthis.#handleCartDataChange(event);\n\t\t\t});\n\t\t}\n\t}\n\n\t#handleCartDataChange(event) {\n\t\tconst updatedCart = event.detail;\n\n\t\tif (updatedCart) {\n\t\t\t// Use calculated_subtotal if available (handles _ignore_price_in_subtotal logic)\n\t\t\t// Otherwise fall back to total_price for backwards compatibility\n\t\t\tlet currentAmount = 0;\n\n\t\t\tif (typeof updatedCart.calculated_subtotal !== 'undefined') {\n\t\t\t\t// calculated_subtotal is already in dollars, no conversion needed\n\t\t\t\tcurrentAmount = updatedCart.calculated_subtotal / 100;\n\t\t\t} else if (typeof updatedCart.total_price !== 'undefined') {\n\t\t\t\t// Convert from cents to dollars if needed (Shopify typically returns cents)\n\t\t\t\tcurrentAmount = updatedCart.total_price / 100;\n\t\t\t}\n\n\t\t\tthis.setCurrentAmount(currentAmount);\n\t\t}\n\t}\n\n\t#updateMessages() {\n\t\tconst isComplete = this.#currentAmount >= this.#minAmount;\n\t\tconst remainingAmount = Math.max(0, this.#minAmount - this.#currentAmount);\n\n\t\t// Format amount with minimal formatting\n\t\tconst formattedAmount = remainingAmount.toFixed(2).replace('.00', '');\n\n\t\t// Update the single message element\n\t\tif (this.#messageElement) {\n\t\t\tlet messageTemplate;\n\n\t\t\tif (isComplete && this.#originalAboveMessage) {\n\t\t\t\t// Show success message when complete\n\t\t\t\tmessageTemplate = this.#originalAboveMessage;\n\t\t\t} else if (!isComplete) {\n\t\t\t\t// Show progress message when incomplete\n\t\t\t\tmessageTemplate = this.#originalBelowMessage || this.#originalAboveMessage;\n\t\t\t}\n\n\t\t\tif (messageTemplate) {\n\t\t\t\t// Support multiple placeholder formats: {amount}, { amount }, [amount]\n\t\t\t\tconst message = messageTemplate\n\t\t\t\t\t.replace(/\\{\\s*amount\\s*\\}/g, formattedAmount)\n\t\t\t\t\t.replace(/\\[\\s*amount\\s*\\]/g, formattedAmount);\n\t\t\t\tthis.#messageElement.textContent = message;\n\t\t\t\tthis.#messageElement.style.display = 'block';\n\t\t\t} else {\n\t\t\t\t// Hide message if no template available for current state\n\t\t\t\tthis.#messageElement.style.display = 'none';\n\t\t\t}\n\t\t}\n\t}\n\n\t#updateComponentState() {\n\t\tconst isComplete = this.#currentAmount >= this.#minAmount;\n\t\tthis.setAttribute('complete', isComplete.toString());\n\t}\n\n\n\t/**\n\t * Public API: Set the progress percentage directly\n\t * @param {number} percent - Progress percentage (0-100)\n\t */\n\tsetPercent(percent) {\n\t\tconst clampedPercent = Math.max(0, Math.min(100, percent));\n\t\tthis.#progressPercent = clampedPercent;\n\n\t\tif (this.#progressBar) {\n\t\t\tthis.#progressBar.setPercent(clampedPercent);\n\t\t}\n\n\t\t// Calculate current amount based on percentage\n\t\tthis.#currentAmount = (clampedPercent / 100) * this.#minAmount;\n\t\tthis.setAttribute('current', this.#currentAmount.toString());\n\n\t\tthis.#updateMessages();\n\t\tthis.#updateComponentState();\n\t}\n\n\t/**\n\t * Public API: Set the current cart amount\n\t * @param {number} amount - Current cart amount\n\t */\n\tsetCurrentAmount(amount) {\n\t\tthis.#currentAmount = parseFloat(amount) || 0;\n\t\tthis.setAttribute('current', this.#currentAmount.toString());\n\t\tthis.#updateProgress();\n\t}\n\n\t/**\n\t * Public API: Set the threshold amount for free shipping\n\t * @param {number} amount - Threshold amount for free shipping\n\t */\n\tsetThresholdAmount(amount) {\n\t\tthis.#minAmount = parseFloat(amount) || 0;\n\t\tthis.setAttribute('threshold', this.#minAmount.toString());\n\t\tthis.#updateProgress();\n\t}\n\n\t/**\n\t * Public API: Set the minimum amount for free shipping (deprecated - use setThresholdAmount)\n\t * @param {number} amount - Minimum amount threshold\n\t * @deprecated Use setThresholdAmount instead\n\t */\n\tsetMinAmount(amount) {\n\t\tthis.setThresholdAmount(amount);\n\t}\n\n\t/**\n\t * Public API: Get current progress information\n\t */\n\tgetProgress() {\n\t\treturn {\n\t\t\tcurrentAmount: this.#currentAmount,\n\t\t\tthresholdAmount: this.#minAmount,\n\t\t\tminAmount: this.#minAmount, // backwards compatibility\n\t\t\tremainingAmount: Math.max(0, this.#minAmount - this.#currentAmount),\n\t\t\tpercent: this.#progressPercent,\n\t\t\tisComplete: this.#currentAmount >= this.#minAmount,\n\t\t};\n\t}\n\n\t/**\n\t * Public API: Update message templates\n\t * @param {string} aboveMessage - Message template for above the bar\n\t * @param {string} belowMessage - Message template for below the bar\n\t */\n\tsetMessages(aboveMessage = null, belowMessage = null) {\n\t\tif (aboveMessage !== null) {\n\t\t\tthis.#originalAboveMessage = aboveMessage;\n\t\t\tthis.setAttribute('message-above', aboveMessage);\n\t\t}\n\n\t\tif (belowMessage !== null) {\n\t\t\tthis.#originalBelowMessage = belowMessage;\n\t\t\tthis.setAttribute('message-below', belowMessage);\n\t\t}\n\n\t\tthis.#updateMessages();\n\t}\n\n\t// Getters\n\tget currentAmount() {\n\t\treturn this.#currentAmount;\n\t}\n\tget thresholdAmount() {\n\t\treturn this.#minAmount;\n\t}\n\tget minAmount() {\n\t\treturn this.#minAmount;\n\t} // backwards compatibility\n\tget percent() {\n\t\treturn this.#progressPercent;\n\t}\n\tget isComplete() {\n\t\treturn this.#currentAmount >= this.#minAmount;\n\t}\n}\n\n// Define CartProgressBar custom element\ncustomElements.define('cart-progress-bar', CartProgressBar);\n\n// Export components for external use\nexport { CartProgressBar, ProgressBar };\n"],"names":[],"mappings":"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"}
|
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
// SCSS Variables (can be overridden before import)
|
|
2
|
-
$cart-progress-bar-height: 12px !default;
|
|
3
|
-
$cart-progress-bar-border-radius: 6px !default;
|
|
4
|
-
$cart-progress-bar-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1) !default;
|
|
5
|
-
$cart-progress-bar-transition-duration: 0.3s !default;
|
|
6
|
-
|
|
7
|
-
// Core color variables
|
|
8
|
-
$cart-progress-section-bg: transparent !default;
|
|
9
|
-
$cart-progress-section-color: #495057 !default;
|
|
10
|
-
$cart-progress-bar-bg: #e9ecef !default;
|
|
11
|
-
$cart-progress-bar-fill-before: #28a745 !default;
|
|
12
|
-
$cart-progress-bar-fill-after: #007bff !default;
|
|
13
|
-
|
|
14
|
-
// Responsive breakpoints
|
|
15
|
-
$cart-progress-mobile-breakpoint: 768px !default;
|
|
16
|
-
|
|
17
|
-
// Cart progress bar component styles
|
|
18
|
-
cart-progress-bar {
|
|
19
|
-
// CSS Custom Properties for customization (mapped from SCSS variables)
|
|
20
|
-
--cart-progress-bar-height: #{$cart-progress-bar-height};
|
|
21
|
-
--cart-progress-bar-border-radius: #{$cart-progress-bar-border-radius};
|
|
22
|
-
--cart-progress-bar-shadow: #{$cart-progress-bar-shadow};
|
|
23
|
-
--cart-progress-bar-transition-duration: #{$cart-progress-bar-transition-duration};
|
|
24
|
-
|
|
25
|
-
// Core color variables
|
|
26
|
-
--cart-progress-section-bg: #{$cart-progress-section-bg};
|
|
27
|
-
--cart-progress-section-color: #{$cart-progress-section-color};
|
|
28
|
-
--cart-progress-bar-bg: #{$cart-progress-bar-bg};
|
|
29
|
-
--cart-progress-bar-fill-before: #{$cart-progress-bar-fill-before};
|
|
30
|
-
--cart-progress-bar-fill-after: #{$cart-progress-bar-fill-after};
|
|
31
|
-
|
|
32
|
-
// Dynamic variables (set by JavaScript)
|
|
33
|
-
--cart-progress-percent: 0%;
|
|
34
|
-
--cart-progress-bar-fill-current: var(--cart-progress-bar-fill-before);
|
|
35
|
-
|
|
36
|
-
display: block;
|
|
37
|
-
width: 100%;
|
|
38
|
-
max-width: 100%;
|
|
39
|
-
background-color: var(--cart-progress-section-bg);
|
|
40
|
-
color: var(--cart-progress-section-color);
|
|
41
|
-
|
|
42
|
-
// Message styling
|
|
43
|
-
p[data-content-cart-progress-message] {
|
|
44
|
-
color: inherit;
|
|
45
|
-
transition: opacity var(--cart-progress-bar-transition-duration) ease;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
// State-based styling
|
|
49
|
-
&[complete='true'] {
|
|
50
|
-
p[data-content-cart-progress-message] {
|
|
51
|
-
font-weight: 600;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// State-based progress bar coloring
|
|
56
|
-
&[complete='false'] {
|
|
57
|
-
--cart-progress-bar-fill-current: var(--cart-progress-bar-fill-before);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
&[complete='true'] {
|
|
61
|
-
--cart-progress-bar-fill-current: var(--cart-progress-bar-fill-after);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
// Progress bar component styles
|
|
66
|
-
progress-bar {
|
|
67
|
-
display: block;
|
|
68
|
-
width: 100%;
|
|
69
|
-
height: var(--cart-progress-bar-height);
|
|
70
|
-
background-color: var(--cart-progress-bar-bg);
|
|
71
|
-
border-radius: var(--cart-progress-bar-border-radius);
|
|
72
|
-
box-shadow: var(--cart-progress-bar-shadow);
|
|
73
|
-
overflow: hidden;
|
|
74
|
-
position: relative;
|
|
75
|
-
|
|
76
|
-
.progress-bar-fill {
|
|
77
|
-
height: 100%;
|
|
78
|
-
width: var(--cart-progress-percent);
|
|
79
|
-
background-color: var(--cart-progress-bar-fill-current);
|
|
80
|
-
border-radius: var(--cart-progress-bar-border-radius);
|
|
81
|
-
transition:
|
|
82
|
-
width var(--cart-progress-bar-transition-duration) ease,
|
|
83
|
-
background-color var(--cart-progress-bar-transition-duration) ease;
|
|
84
|
-
position: relative;
|
|
85
|
-
|
|
86
|
-
// Subtle gradient effect
|
|
87
|
-
background-image: linear-gradient(
|
|
88
|
-
45deg,
|
|
89
|
-
rgba(255, 255, 255, 0.1) 25%,
|
|
90
|
-
transparent 25%,
|
|
91
|
-
transparent 50%,
|
|
92
|
-
rgba(255, 255, 255, 0.1) 50%,
|
|
93
|
-
rgba(255, 255, 255, 0.1) 75%,
|
|
94
|
-
transparent 75%,
|
|
95
|
-
transparent
|
|
96
|
-
);
|
|
97
|
-
background-size: 12px 12px;
|
|
98
|
-
|
|
99
|
-
// Shine effect for completed state
|
|
100
|
-
&::after {
|
|
101
|
-
content: '';
|
|
102
|
-
position: absolute;
|
|
103
|
-
top: 0;
|
|
104
|
-
left: -100%;
|
|
105
|
-
width: 100%;
|
|
106
|
-
height: 100%;
|
|
107
|
-
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.4), transparent);
|
|
108
|
-
transition: left 0.5s ease;
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
// Animate shine effect when complete
|
|
113
|
-
cart-progress-bar[complete='true'] & {
|
|
114
|
-
.progress-bar-fill::after {
|
|
115
|
-
left: 100%;
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
// Accessibility improvements
|
|
120
|
-
&:focus-visible {
|
|
121
|
-
outline: 2px solid #007bff;
|
|
122
|
-
outline-offset: 2px;
|
|
123
|
-
}
|
|
124
|
-
}
|