@magic-spells/cart-progress-bar 0.2.0 → 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 +31 -12
- package/dist/cart-progress-bar.cjs.js +164 -242
- package/dist/cart-progress-bar.cjs.js.map +1 -1
- package/dist/cart-progress-bar.esm.js +164 -242
- package/dist/cart-progress-bar.esm.js.map +1 -1
- package/dist/cart-progress-bar.js +164 -242
- package/dist/cart-progress-bar.js.map +1 -1
- package/dist/cart-progress-bar.min.js +1 -1
- package/package.json +4 -4
- package/src/cart-progress-bar.js +164 -242
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@ A beautiful, accessible cart progress bar web component for free shipping thresh
|
|
|
6
6
|
|
|
7
7
|
## Features
|
|
8
8
|
|
|
9
|
-
- 🎯 **Smart Messaging** - Template-based messages with
|
|
9
|
+
- 🎯 **Smart Messaging** - Template-based messages with flexible placeholder formats
|
|
10
10
|
- 🎨 **Simplified Theming** - Just 5 CSS variables to control all colors and appearance
|
|
11
11
|
- 📱 **Responsive** - Mobile-optimized with responsive breakpoints
|
|
12
12
|
- ⚡ **Smooth Animations** - Buttery smooth transitions and completion effects
|
|
@@ -25,8 +25,8 @@ npm install @magic-spells/cart-progress-bar
|
|
|
25
25
|
threshold="75.00"
|
|
26
26
|
current="25.50"
|
|
27
27
|
message-above="🎉 Congratulations! You've qualified for FREE shipping!"
|
|
28
|
-
message-below="Add { amount } more for FREE shipping!">
|
|
29
|
-
<p data-content-cart-progress-message>Add { amount } more for FREE shipping!</p>
|
|
28
|
+
message-below="Add ${ amount } more for FREE shipping!">
|
|
29
|
+
<p data-content-cart-progress-message>Add ${ amount } more for FREE shipping!</p>
|
|
30
30
|
<progress-bar></progress-bar>
|
|
31
31
|
</cart-progress-bar>
|
|
32
32
|
```
|
|
@@ -54,7 +54,7 @@ const info = progressBar.getProgress();
|
|
|
54
54
|
console.log(info.percent, info.isComplete, info.thresholdAmount);
|
|
55
55
|
|
|
56
56
|
// Update message templates
|
|
57
|
-
progressBar.setMessages('Almost there!', 'Only { amount } more to go!');
|
|
57
|
+
progressBar.setMessages('Almost there!', 'Only ${ amount } more to go!');
|
|
58
58
|
```
|
|
59
59
|
|
|
60
60
|
## Cart Integration
|
|
@@ -63,7 +63,7 @@ The component automatically listens for cart data changes when placed inside a `
|
|
|
63
63
|
|
|
64
64
|
```html
|
|
65
65
|
<cart-dialog>
|
|
66
|
-
<cart-progress-bar threshold="75.00" message-below="Add { amount } more for FREE shipping!">
|
|
66
|
+
<cart-progress-bar threshold="75.00" message-below="Add ${ amount } more for FREE shipping!">
|
|
67
67
|
</cart-progress-bar>
|
|
68
68
|
</cart-dialog>
|
|
69
69
|
```
|
|
@@ -86,7 +86,7 @@ The progress bar uses intelligent pricing calculation:
|
|
|
86
86
|
| `threshold` | Threshold amount for free shipping | `"75.00"` |
|
|
87
87
|
| `current` | Current cart amount | `"25.50"` |
|
|
88
88
|
| `message-above` | Success message when threshold is reached | `"🎉 FREE shipping unlocked!"` |
|
|
89
|
-
| `message-below` | Message template shown below the bar | `"Add { amount } more!"` |
|
|
89
|
+
| `message-below` | Message template shown below the bar | `"Add ${ amount } more!"` |
|
|
90
90
|
|
|
91
91
|
## Customization
|
|
92
92
|
|
|
@@ -130,21 +130,40 @@ cart-progress-bar {
|
|
|
130
130
|
|
|
131
131
|
## Message Templates
|
|
132
132
|
|
|
133
|
-
Use
|
|
133
|
+
Use placeholder formats in your message templates and include the currency symbol:
|
|
134
134
|
|
|
135
135
|
```html
|
|
136
136
|
<cart-progress-bar
|
|
137
137
|
message-above="🎉 FREE shipping unlocked!"
|
|
138
|
-
message-below="You need { amount } more for free shipping!">
|
|
139
|
-
<p data-content-cart-progress-message>You need { amount } more for free shipping!</p>
|
|
138
|
+
message-below="You need ${ amount } more for free shipping!">
|
|
139
|
+
<p data-content-cart-progress-message>You need ${ amount } more for free shipping!</p>
|
|
140
140
|
</cart-progress-bar>
|
|
141
141
|
```
|
|
142
142
|
|
|
143
|
+
### Supported Placeholder Formats
|
|
144
|
+
|
|
145
|
+
- `{ amount }` - spaces around amount
|
|
146
|
+
- `{amount}` - no spaces
|
|
147
|
+
- `[amount]` - square brackets (with or without spaces)
|
|
148
|
+
|
|
149
|
+
### Examples
|
|
150
|
+
|
|
151
|
+
```html
|
|
152
|
+
<!-- Dollar amounts -->
|
|
153
|
+
<cart-progress-bar message-below="Add ${ amount } more for free shipping!">
|
|
154
|
+
|
|
155
|
+
<!-- Euro amounts -->
|
|
156
|
+
<cart-progress-bar message-below="Only €{amount} left to unlock free delivery!">
|
|
157
|
+
|
|
158
|
+
<!-- With square brackets -->
|
|
159
|
+
<cart-progress-bar message-below="Just £[amount] more to go!">
|
|
160
|
+
```
|
|
161
|
+
|
|
143
162
|
The component automatically:
|
|
144
163
|
|
|
145
|
-
- Shows `message-below` when incomplete (with
|
|
146
|
-
- Shows `message-above` when threshold is reached (success message)
|
|
147
|
-
- Formats
|
|
164
|
+
- Shows `message-below` when incomplete (with placeholder replaced with remaining amount)
|
|
165
|
+
- Shows `message-above` when threshold is reached (success message)
|
|
166
|
+
- Formats amounts as minimal decimal numbers (removes .00 for whole amounts)
|
|
148
167
|
- Updates messages when amounts change
|
|
149
168
|
- Switches between before/after progress bar colors based on completion status
|
|
150
169
|
|
|
@@ -6,23 +6,18 @@
|
|
|
6
6
|
class ProgressBar extends HTMLElement {
|
|
7
7
|
constructor() {
|
|
8
8
|
super();
|
|
9
|
-
this
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
this.setAttribute('aria-valuemax', '100');
|
|
16
|
-
this.setAttribute('aria-valuenow', '0');
|
|
17
|
-
|
|
18
|
-
// Create the visual progress bar
|
|
19
|
-
this.innerHTML = '<div class="progress-bar-fill"></div>';
|
|
9
|
+
const _ = this;
|
|
10
|
+
_.setAttribute('role', 'progressbar');
|
|
11
|
+
_.setAttribute('aria-valuemin', '0');
|
|
12
|
+
_.setAttribute('aria-valuemax', '100');
|
|
13
|
+
_.setAttribute('aria-valuenow', '0');
|
|
14
|
+
_.innerHTML = '<div class="progress-bar-fill"></div>';
|
|
20
15
|
}
|
|
21
16
|
|
|
22
17
|
setPercent(percent) {
|
|
23
|
-
const
|
|
24
|
-
this.style.setProperty('--cart-progress-percent', `${
|
|
25
|
-
this.setAttribute('aria-valuenow',
|
|
18
|
+
const p = Math.max(0, Math.min(100, percent));
|
|
19
|
+
this.style.setProperty('--cart-progress-percent', `${p}%`);
|
|
20
|
+
this.setAttribute('aria-valuenow', p);
|
|
26
21
|
}
|
|
27
22
|
}
|
|
28
23
|
|
|
@@ -34,303 +29,230 @@ customElements.define('progress-bar', ProgressBar);
|
|
|
34
29
|
*/
|
|
35
30
|
class CartProgressBar extends HTMLElement {
|
|
36
31
|
// Private fields
|
|
37
|
-
#
|
|
38
|
-
#
|
|
39
|
-
#
|
|
40
|
-
#
|
|
41
|
-
#
|
|
42
|
-
#
|
|
43
|
-
#
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
*/
|
|
32
|
+
#threshold = 0;
|
|
33
|
+
#current = 0;
|
|
34
|
+
#percent = 0;
|
|
35
|
+
#msgAbove = '';
|
|
36
|
+
#msgBelow = '';
|
|
37
|
+
#bar = null;
|
|
38
|
+
#msgEl = null;
|
|
39
|
+
#moneyFmt = null;
|
|
40
|
+
#debounce = null;
|
|
41
|
+
|
|
48
42
|
static get observedAttributes() {
|
|
49
|
-
return ['threshold', 'current', 'message-above', 'message-below'];
|
|
43
|
+
return ['threshold', 'current', 'message-above', 'message-below', 'money-format'];
|
|
50
44
|
}
|
|
51
45
|
|
|
52
46
|
constructor() {
|
|
53
47
|
super();
|
|
54
|
-
this
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
this.#currentAmount = parseFloat(this.getAttribute('current')) || 0;
|
|
61
|
-
|
|
62
|
-
// Store original message templates
|
|
63
|
-
this.#originalAboveMessage = this.getAttribute('message-above') || '';
|
|
64
|
-
this.#originalBelowMessage = this.getAttribute('message-below') || '';
|
|
48
|
+
const _ = this;
|
|
49
|
+
_.#threshold = parseFloat(_.getAttribute('threshold')) || 0;
|
|
50
|
+
_.#current = parseFloat(_.getAttribute('current')) || 0;
|
|
51
|
+
_.#msgAbove = _.getAttribute('message-above') || '';
|
|
52
|
+
_.#msgBelow = _.getAttribute('message-below') || '';
|
|
53
|
+
_.#moneyFmt = _.getAttribute('money-format');
|
|
65
54
|
}
|
|
66
55
|
|
|
67
56
|
async connectedCallback() {
|
|
68
|
-
// ensure the child custom element has been registered
|
|
69
57
|
await customElements.whenDefined('progress-bar');
|
|
70
|
-
|
|
71
|
-
if (!customElements.get('progress-bar')) {
|
|
72
|
-
throw new Error('<progress-bar> must be registered before <cart-progress-bar> runs');
|
|
73
|
-
}
|
|
74
|
-
|
|
75
58
|
this.#render();
|
|
76
59
|
this.#updateProgress();
|
|
77
60
|
this.#attachListeners();
|
|
78
61
|
}
|
|
79
62
|
|
|
80
|
-
|
|
81
|
-
if (
|
|
63
|
+
disconnectedCallback() {
|
|
64
|
+
if (this.#debounce) clearTimeout(this.#debounce);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
attributeChangedCallback(name, oldVal, newVal) {
|
|
68
|
+
if (oldVal === newVal) return;
|
|
69
|
+
const _ = this;
|
|
82
70
|
|
|
83
71
|
switch (name) {
|
|
84
72
|
case 'threshold':
|
|
85
|
-
|
|
86
|
-
|
|
73
|
+
_.#threshold = parseFloat(newVal) || 0;
|
|
74
|
+
_.#updateProgress();
|
|
87
75
|
break;
|
|
88
76
|
case 'current':
|
|
89
|
-
|
|
90
|
-
|
|
77
|
+
_.#current = parseFloat(newVal) || 0;
|
|
78
|
+
_.#updateProgress();
|
|
91
79
|
break;
|
|
92
80
|
case 'message-above':
|
|
93
|
-
|
|
94
|
-
|
|
81
|
+
_.#msgAbove = newVal || '';
|
|
82
|
+
_.#updateMessages();
|
|
95
83
|
break;
|
|
96
84
|
case 'message-below':
|
|
97
|
-
|
|
98
|
-
|
|
85
|
+
_.#msgBelow = newVal || '';
|
|
86
|
+
_.#updateMessages();
|
|
87
|
+
break;
|
|
88
|
+
case 'money-format':
|
|
89
|
+
_.#moneyFmt = newVal;
|
|
90
|
+
_.#updateMessages();
|
|
99
91
|
break;
|
|
100
92
|
}
|
|
101
93
|
}
|
|
102
94
|
|
|
103
95
|
#render() {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
//
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
this.#messageElement = document.createElement('p');
|
|
115
|
-
this.#messageElement.setAttribute('data-content-cart-progress-message', '');
|
|
116
|
-
this.appendChild(this.#messageElement);
|
|
96
|
+
const _ = this;
|
|
97
|
+
// Find existing elements or create them
|
|
98
|
+
_.#msgEl = _.querySelector('[data-content-cart-progress-message]');
|
|
99
|
+
_.#bar = _.querySelector('progress-bar');
|
|
100
|
+
|
|
101
|
+
// Create message element if needed
|
|
102
|
+
if (!_.#msgEl && (_.#msgAbove || _.#msgBelow)) {
|
|
103
|
+
_.#msgEl = document.createElement('p');
|
|
104
|
+
_.#msgEl.setAttribute('data-content-cart-progress-message', '');
|
|
105
|
+
_.appendChild(_.#msgEl);
|
|
117
106
|
}
|
|
118
107
|
|
|
119
|
-
// Create progress bar if
|
|
120
|
-
if (!
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
this.#progressBar = document.createElement('progress-bar');
|
|
124
|
-
this.appendChild(this.#progressBar);
|
|
125
|
-
} else {
|
|
126
|
-
// Fallback: wait for definition
|
|
127
|
-
customElements.whenDefined('progress-bar').then(() => {
|
|
128
|
-
if (!this.#progressBar) {
|
|
129
|
-
this.#progressBar = document.createElement('progress-bar');
|
|
130
|
-
this.appendChild(this.#progressBar);
|
|
131
|
-
this.#updateProgress(); // Update progress after creating
|
|
132
|
-
}
|
|
133
|
-
});
|
|
134
|
-
}
|
|
108
|
+
// Create progress bar if needed
|
|
109
|
+
if (!_.#bar) {
|
|
110
|
+
_.#bar = document.createElement('progress-bar');
|
|
111
|
+
_.appendChild(_.#bar);
|
|
135
112
|
}
|
|
136
113
|
}
|
|
137
114
|
|
|
138
115
|
#updateProgress() {
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
// Update progress bar
|
|
146
|
-
if (this.#progressBar) {
|
|
147
|
-
this.#progressBar.setPercent(this.#progressPercent);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
// Update messages
|
|
151
|
-
this.#updateMessages();
|
|
152
|
-
|
|
153
|
-
// Update component state
|
|
154
|
-
this.#updateComponentState();
|
|
116
|
+
const _ = this;
|
|
117
|
+
const converted = _.#converted();
|
|
118
|
+
_.#percent = converted === 0 ? 100 : Math.min(100, (_.#current / converted) * 100);
|
|
119
|
+
if (_.#bar) _.#bar.setPercent(_.#percent);
|
|
120
|
+
_.#updateState(converted);
|
|
155
121
|
}
|
|
156
122
|
|
|
157
123
|
#attachListeners() {
|
|
158
|
-
|
|
159
|
-
const
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
// Listen for cart data changes
|
|
163
|
-
cartDialog.addEventListener('cart-dialog:data-changed', (event) => {
|
|
164
|
-
this.#handleCartDataChange(event);
|
|
165
|
-
});
|
|
124
|
+
const _ = this;
|
|
125
|
+
const panel = _.closest('cart-panel');
|
|
126
|
+
if (panel) {
|
|
127
|
+
panel.addEventListener('cart-panel:data-changed', (e) => _.#onCartChange(e));
|
|
166
128
|
}
|
|
167
129
|
}
|
|
168
130
|
|
|
169
|
-
#
|
|
170
|
-
const
|
|
171
|
-
|
|
172
|
-
if (
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
if (
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
// Convert from cents to dollars if needed (Shopify typically returns cents)
|
|
182
|
-
currentAmount = updatedCart.total_price / 100;
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
this.setCurrentAmount(currentAmount);
|
|
186
|
-
}
|
|
131
|
+
#onCartChange(event) {
|
|
132
|
+
const _ = this;
|
|
133
|
+
const cart = event.detail;
|
|
134
|
+
if (!cart) return;
|
|
135
|
+
|
|
136
|
+
if (_.#debounce) clearTimeout(_.#debounce);
|
|
137
|
+
_.#debounce = setTimeout(() => {
|
|
138
|
+
_.#debounce = null;
|
|
139
|
+
// Use calculated_subtotal if available, else total_price (both in cents)
|
|
140
|
+
const amt = (cart.calculated_subtotal ?? cart.total_price ?? 0) / 100;
|
|
141
|
+
_.setCurrentAmount(amt);
|
|
142
|
+
}, 100);
|
|
187
143
|
}
|
|
188
144
|
|
|
189
|
-
#
|
|
190
|
-
const
|
|
191
|
-
const
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
// Show success message when complete
|
|
202
|
-
messageTemplate = this.#originalAboveMessage;
|
|
203
|
-
} else if (!isComplete) {
|
|
204
|
-
// Show progress message when incomplete
|
|
205
|
-
messageTemplate = this.#originalBelowMessage || this.#originalAboveMessage;
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
if (messageTemplate) {
|
|
209
|
-
const message = messageTemplate.replace('{ amount }', formattedAmount);
|
|
210
|
-
this.#messageElement.textContent = message;
|
|
211
|
-
this.#messageElement.style.display = 'block';
|
|
145
|
+
#updateState(converted) {
|
|
146
|
+
const _ = this;
|
|
147
|
+
const complete = _.#current >= converted;
|
|
148
|
+
const remaining = Math.max(0, converted - _.#current);
|
|
149
|
+
const formatted = _.#fmtMoney(remaining);
|
|
150
|
+
|
|
151
|
+
// Update message
|
|
152
|
+
if (_.#msgEl) {
|
|
153
|
+
let tpl = complete ? _.#msgAbove : (_.#msgBelow || _.#msgAbove);
|
|
154
|
+
if (tpl) {
|
|
155
|
+
_.#msgEl.textContent = tpl.replace(/\[\s*amount\s*\]/g, formatted);
|
|
156
|
+
_.#msgEl.style.display = 'block';
|
|
212
157
|
} else {
|
|
213
|
-
|
|
214
|
-
this.#messageElement.style.display = 'none';
|
|
158
|
+
_.#msgEl.style.display = 'none';
|
|
215
159
|
}
|
|
216
160
|
}
|
|
217
|
-
}
|
|
218
161
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
this.setAttribute('complete', isComplete.toString());
|
|
162
|
+
// Update complete attribute
|
|
163
|
+
_.setAttribute('complete', complete.toString());
|
|
222
164
|
}
|
|
223
165
|
|
|
224
|
-
#
|
|
225
|
-
|
|
226
|
-
return
|
|
227
|
-
style: 'currency',
|
|
228
|
-
currency: 'USD',
|
|
229
|
-
minimumFractionDigits: 2,
|
|
230
|
-
maximumFractionDigits: 2,
|
|
231
|
-
})
|
|
232
|
-
.format(amount)
|
|
233
|
-
.replace('.00', '');
|
|
234
|
-
}
|
|
166
|
+
#fmtMoney(amt) {
|
|
167
|
+
const fmt = this.#moneyFmt;
|
|
168
|
+
if (!fmt) return amt.toFixed(2).replace(/\.00$/, '');
|
|
235
169
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
setPercent(percent) {
|
|
241
|
-
const clampedPercent = Math.max(0, Math.min(100, percent));
|
|
242
|
-
this.#progressPercent = clampedPercent;
|
|
170
|
+
const fixed = amt.toFixed(2);
|
|
171
|
+
const noDecimals = Math.round(amt).toString();
|
|
172
|
+
const withComma = fixed.replace('.', ',');
|
|
173
|
+
const noDecWithComma = noDecimals.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
|
|
243
174
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
175
|
+
return fmt
|
|
176
|
+
.replace(/\{\{\s*amount_no_decimals_with_comma_separator\s*\}\}/g, noDecWithComma)
|
|
177
|
+
.replace(/\{\{\s*amount_with_comma_separator\s*\}\}/g, withComma)
|
|
178
|
+
.replace(/\{\{\s*amount_no_decimals\s*\}\}/g, noDecimals)
|
|
179
|
+
.replace(/\{\{\s*amount\s*\}\}/g, fixed);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
#converted() {
|
|
183
|
+
const rate = parseFloat(window.Shopify?.currency?.rate) || 1;
|
|
184
|
+
return this.#threshold * rate;
|
|
185
|
+
}
|
|
247
186
|
|
|
248
|
-
|
|
249
|
-
this.#
|
|
250
|
-
|
|
187
|
+
#updateMessages() {
|
|
188
|
+
this.#updateState(this.#converted());
|
|
189
|
+
}
|
|
251
190
|
|
|
252
|
-
|
|
253
|
-
|
|
191
|
+
// Public API
|
|
192
|
+
setPercent(pct) {
|
|
193
|
+
const _ = this;
|
|
194
|
+
const p = Math.max(0, Math.min(100, pct));
|
|
195
|
+
_.#percent = p;
|
|
196
|
+
if (_.#bar) _.#bar.setPercent(p);
|
|
197
|
+
// Use converted threshold for multi-currency consistency
|
|
198
|
+
_.#current = (p / 100) * _.#converted();
|
|
199
|
+
_.setAttribute('current', _.#current.toString());
|
|
200
|
+
_.#updateState(_.#converted());
|
|
254
201
|
}
|
|
255
202
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
this.#currentAmount = parseFloat(amount) || 0;
|
|
262
|
-
this.setAttribute('current', this.#currentAmount.toString());
|
|
263
|
-
this.#updateProgress();
|
|
203
|
+
setCurrentAmount(amt) {
|
|
204
|
+
const _ = this;
|
|
205
|
+
_.#current = parseFloat(amt) || 0;
|
|
206
|
+
_.setAttribute('current', _.#current.toString());
|
|
207
|
+
_.#updateProgress();
|
|
264
208
|
}
|
|
265
209
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
this.#minAmount = parseFloat(amount) || 0;
|
|
272
|
-
this.setAttribute('threshold', this.#minAmount.toString());
|
|
273
|
-
this.#updateProgress();
|
|
210
|
+
setThresholdAmount(amt) {
|
|
211
|
+
const _ = this;
|
|
212
|
+
_.#threshold = parseFloat(amt) || 0;
|
|
213
|
+
_.setAttribute('threshold', _.#threshold.toString());
|
|
214
|
+
_.#updateProgress();
|
|
274
215
|
}
|
|
275
216
|
|
|
276
|
-
/**
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
* @deprecated Use setThresholdAmount instead
|
|
280
|
-
*/
|
|
281
|
-
setMinAmount(amount) {
|
|
282
|
-
this.setThresholdAmount(amount);
|
|
217
|
+
/** @deprecated Use setThresholdAmount */
|
|
218
|
+
setMinAmount(amt) {
|
|
219
|
+
this.setThresholdAmount(amt);
|
|
283
220
|
}
|
|
284
221
|
|
|
285
|
-
/**
|
|
286
|
-
* Public API: Get current progress information
|
|
287
|
-
*/
|
|
288
222
|
getProgress() {
|
|
223
|
+
const _ = this;
|
|
224
|
+
const converted = _.#converted();
|
|
289
225
|
return {
|
|
290
|
-
currentAmount:
|
|
291
|
-
thresholdAmount:
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
226
|
+
currentAmount: _.#current,
|
|
227
|
+
thresholdAmount: _.#threshold,
|
|
228
|
+
convertedThreshold: converted,
|
|
229
|
+
minAmount: _.#threshold,
|
|
230
|
+
remainingAmount: Math.max(0, converted - _.#current),
|
|
231
|
+
percent: _.#percent,
|
|
232
|
+
isComplete: _.#current >= converted,
|
|
233
|
+
currencyRate: parseFloat(window.Shopify?.currency?.rate) || 1,
|
|
296
234
|
};
|
|
297
235
|
}
|
|
298
236
|
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
setMessages(aboveMessage = null, belowMessage = null) {
|
|
305
|
-
if (aboveMessage !== null) {
|
|
306
|
-
this.#originalAboveMessage = aboveMessage;
|
|
307
|
-
this.setAttribute('message-above', aboveMessage);
|
|
237
|
+
setMessages(above = null, below = null) {
|
|
238
|
+
const _ = this;
|
|
239
|
+
if (above !== null) {
|
|
240
|
+
_.#msgAbove = above;
|
|
241
|
+
_.setAttribute('message-above', above);
|
|
308
242
|
}
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
this.setAttribute('message-below', belowMessage);
|
|
243
|
+
if (below !== null) {
|
|
244
|
+
_.#msgBelow = below;
|
|
245
|
+
_.setAttribute('message-below', below);
|
|
313
246
|
}
|
|
314
|
-
|
|
315
|
-
this.#updateMessages();
|
|
247
|
+
_.#updateMessages();
|
|
316
248
|
}
|
|
317
249
|
|
|
318
|
-
// Getters
|
|
319
|
-
get currentAmount() {
|
|
320
|
-
|
|
321
|
-
}
|
|
322
|
-
get
|
|
323
|
-
|
|
324
|
-
}
|
|
325
|
-
get minAmount() {
|
|
326
|
-
return this.#minAmount;
|
|
327
|
-
} // backwards compatibility
|
|
328
|
-
get percent() {
|
|
329
|
-
return this.#progressPercent;
|
|
330
|
-
}
|
|
331
|
-
get isComplete() {
|
|
332
|
-
return this.#currentAmount >= this.#minAmount;
|
|
333
|
-
}
|
|
250
|
+
// Getters (with backwards compatibility)
|
|
251
|
+
get currentAmount() { return this.#current; }
|
|
252
|
+
get thresholdAmount() { return this.#threshold; }
|
|
253
|
+
get minAmount() { return this.#threshold; }
|
|
254
|
+
get percent() { return this.#percent; }
|
|
255
|
+
get isComplete() { return this.#current >= this.#converted(); }
|
|
334
256
|
}
|
|
335
257
|
|
|
336
258
|
// Define CartProgressBar custom element
|