@magic-spells/cart-panel 0.1.0 → 0.1.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/README.md +191 -226
- package/dist/cart-panel.cjs.css +51 -10
- package/dist/cart-panel.cjs.js +9 -3
- package/dist/cart-panel.cjs.js.map +1 -1
- package/dist/cart-panel.css +51 -10
- package/dist/cart-panel.esm.css +51 -10
- package/dist/cart-panel.esm.js +9 -3
- package/dist/cart-panel.esm.js.map +1 -1
- package/dist/cart-panel.js +1074 -950
- package/dist/cart-panel.js.map +1 -1
- package/dist/cart-panel.min.css +1 -1
- package/dist/cart-panel.min.js +1 -1
- package/dist/cart-panel.scss +73 -73
- package/package.json +80 -80
- package/src/cart-panel.js +9 -3
- package/src/cart-panel.scss +73 -73
package/README.md
CHANGED
|
@@ -42,44 +42,44 @@ Or include directly in your HTML:
|
|
|
42
42
|
```html
|
|
43
43
|
<!-- Trigger button -->
|
|
44
44
|
<button aria-haspopup="dialog" aria-controls="my-cart" aria-expanded="false">
|
|
45
|
-
|
|
45
|
+
Open Cart (3 items)
|
|
46
46
|
</button>
|
|
47
47
|
|
|
48
48
|
<!-- Cart modal dialog -->
|
|
49
49
|
<cart-dialog id="my-cart" aria-labelledby="cart-title">
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
50
|
+
<cart-panel>
|
|
51
|
+
<div class="cart-header">
|
|
52
|
+
<h2 id="cart-title">Shopping Cart</h2>
|
|
53
|
+
<button data-action="hide-cart" aria-label="Close cart">×</button>
|
|
54
|
+
</div>
|
|
55
|
+
|
|
56
|
+
<div class="cart-body">
|
|
57
|
+
<!-- Cart items using @magic-spells/cart-item -->
|
|
58
|
+
<cart-item data-key="shopify-line-item-123">
|
|
59
|
+
<cart-item-content>
|
|
60
|
+
<div class="product-info">
|
|
61
|
+
<img src="product.jpg" alt="Product" />
|
|
62
|
+
<div>
|
|
63
|
+
<h4>Awesome T-Shirt</h4>
|
|
64
|
+
<div class="price">$29.99</div>
|
|
65
|
+
</div>
|
|
66
|
+
</div>
|
|
67
|
+
<div class="quantity-controls">
|
|
68
|
+
<input type="number" data-cart-quantity value="1" min="1" />
|
|
69
|
+
<button data-action="remove">Remove</button>
|
|
70
|
+
</div>
|
|
71
|
+
</cart-item-content>
|
|
72
|
+
<cart-item-processing>
|
|
73
|
+
<div>Processing...</div>
|
|
74
|
+
</cart-item-processing>
|
|
75
|
+
</cart-item>
|
|
76
|
+
</div>
|
|
77
|
+
|
|
78
|
+
<div class="cart-footer">
|
|
79
|
+
<div class="cart-total">Total: $29.99</div>
|
|
80
|
+
<button class="checkout-btn">Checkout</button>
|
|
81
|
+
</div>
|
|
82
|
+
</cart-panel>
|
|
83
83
|
</cart-dialog>
|
|
84
84
|
```
|
|
85
85
|
|
|
@@ -132,28 +132,28 @@ Example:
|
|
|
132
132
|
```html
|
|
133
133
|
<!-- Minimal cart modal -->
|
|
134
134
|
<cart-dialog id="simple-cart">
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
135
|
+
<cart-panel>
|
|
136
|
+
<h2>Cart</h2>
|
|
137
|
+
<button data-action="hide-cart">Close</button>
|
|
138
|
+
<!-- Cart content here -->
|
|
139
|
+
</cart-panel>
|
|
140
140
|
</cart-dialog>
|
|
141
141
|
|
|
142
142
|
<!-- Complete cart with all features -->
|
|
143
143
|
<cart-dialog id="full-cart" aria-modal="true" aria-labelledby="cart-heading">
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
144
|
+
<cart-overlay></cart-overlay>
|
|
145
|
+
<cart-panel>
|
|
146
|
+
<header class="cart-header">
|
|
147
|
+
<h2 id="cart-heading">Shopping Cart</h2>
|
|
148
|
+
<button data-action="hide-cart" aria-label="Close cart">×</button>
|
|
149
|
+
</header>
|
|
150
|
+
<div class="cart-content">
|
|
151
|
+
<!-- Cart items will be rendered here -->
|
|
152
|
+
</div>
|
|
153
|
+
<footer class="cart-footer">
|
|
154
|
+
<button class="checkout-btn">Checkout</button>
|
|
155
|
+
</footer>
|
|
156
|
+
</cart-panel>
|
|
157
157
|
</cart-dialog>
|
|
158
158
|
```
|
|
159
159
|
|
|
@@ -166,52 +166,52 @@ The component provides complete styling control through CSS custom properties an
|
|
|
166
166
|
```css
|
|
167
167
|
/* Customize modal positioning and sizing */
|
|
168
168
|
cart-dialog {
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
169
|
+
--cart-panel-width: min(500px, 95vw);
|
|
170
|
+
--cart-panel-z-index: 9999;
|
|
171
|
+
--cart-overlay-z-index: 9998;
|
|
172
172
|
}
|
|
173
173
|
|
|
174
174
|
/* Customize overlay appearance */
|
|
175
175
|
cart-overlay {
|
|
176
|
-
|
|
177
|
-
|
|
176
|
+
--cart-overlay-background: rgba(0, 0, 0, 0.3);
|
|
177
|
+
--cart-overlay-backdrop-filter: blur(8px);
|
|
178
178
|
}
|
|
179
179
|
|
|
180
180
|
/* Customize panel styling */
|
|
181
181
|
cart-panel {
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
182
|
+
--cart-panel-background: #ffffff;
|
|
183
|
+
--cart-panel-shadow: -10px 0 30px rgba(0, 0, 0, 0.2);
|
|
184
|
+
--cart-panel-border-radius: 12px 0 0 12px;
|
|
185
185
|
}
|
|
186
186
|
|
|
187
187
|
/* Customize animations */
|
|
188
188
|
cart-dialog {
|
|
189
|
-
|
|
190
|
-
|
|
189
|
+
--cart-transition-duration: 400ms;
|
|
190
|
+
--cart-transition-timing: cubic-bezier(0.25, 0.8, 0.25, 1);
|
|
191
191
|
}
|
|
192
192
|
|
|
193
193
|
/* Style your cart content layout */
|
|
194
194
|
cart-panel {
|
|
195
|
-
|
|
196
|
-
|
|
195
|
+
display: flex;
|
|
196
|
+
flex-direction: column;
|
|
197
197
|
}
|
|
198
198
|
|
|
199
199
|
.cart-header {
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
200
|
+
padding: 1.5rem;
|
|
201
|
+
border-bottom: 1px solid #eee;
|
|
202
|
+
background: #f8f9fa;
|
|
203
203
|
}
|
|
204
204
|
|
|
205
205
|
.cart-content {
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
206
|
+
flex: 1;
|
|
207
|
+
overflow-y: auto;
|
|
208
|
+
padding: 1rem;
|
|
209
209
|
}
|
|
210
210
|
|
|
211
211
|
.cart-footer {
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
212
|
+
padding: 1.5rem;
|
|
213
|
+
border-top: 1px solid #eee;
|
|
214
|
+
background: #f8f9fa;
|
|
215
215
|
}
|
|
216
216
|
```
|
|
217
217
|
|
|
@@ -238,26 +238,26 @@ The component supports both CSS custom properties and SCSS variables for maximum
|
|
|
238
238
|
```css
|
|
239
239
|
/* Dramatic slide-in effect */
|
|
240
240
|
.dramatic-cart {
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
241
|
+
--cart-transition-duration: 600ms;
|
|
242
|
+
--cart-transition-timing: cubic-bezier(0.68, -0.55, 0.265, 1.55);
|
|
243
|
+
--cart-overlay-background: rgba(0, 0, 0, 0.4);
|
|
244
|
+
--cart-overlay-backdrop-filter: blur(10px);
|
|
245
245
|
}
|
|
246
246
|
|
|
247
247
|
/* Subtle minimal styling */
|
|
248
248
|
.minimal-cart {
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
249
|
+
--cart-panel-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
|
250
|
+
--cart-panel-border-radius: 8px;
|
|
251
|
+
--cart-transition-duration: 200ms;
|
|
252
|
+
--cart-overlay-background: rgba(0, 0, 0, 0.05);
|
|
253
253
|
}
|
|
254
254
|
|
|
255
255
|
/* Mobile-optimized full-width */
|
|
256
256
|
@media (max-width: 768px) {
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
257
|
+
.mobile-cart {
|
|
258
|
+
--cart-panel-width: 100vw;
|
|
259
|
+
--cart-panel-border-radius: 0;
|
|
260
|
+
}
|
|
261
261
|
}
|
|
262
262
|
```
|
|
263
263
|
|
|
@@ -276,8 +276,8 @@ $cart-overlay-background: rgba(0, 0, 0, 0.25);
|
|
|
276
276
|
@import '@magic-spells/cart-panel/css';
|
|
277
277
|
|
|
278
278
|
.my-store cart-dialog {
|
|
279
|
-
|
|
280
|
-
|
|
279
|
+
--cart-transition-duration: 400ms;
|
|
280
|
+
--cart-panel-background: #f8f9fa;
|
|
281
281
|
}
|
|
282
282
|
```
|
|
283
283
|
|
|
@@ -330,32 +330,32 @@ await cartDialog.refreshCart();
|
|
|
330
330
|
|
|
331
331
|
// Event emitter pattern (recommended)
|
|
332
332
|
cartDialog
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
333
|
+
.on('cart-dialog:show', (e) => {
|
|
334
|
+
console.log('Cart opened by:', e.detail.triggerElement);
|
|
335
|
+
})
|
|
336
|
+
.on('cart-dialog:data-changed', (cartData) => {
|
|
337
|
+
console.log('Cart updated:', cartData);
|
|
338
|
+
// Update header cart count, etc.
|
|
339
|
+
});
|
|
340
340
|
|
|
341
341
|
// Traditional event listeners (also supported)
|
|
342
342
|
cartDialog.addEventListener('cart-item:remove', (e) => {
|
|
343
|
-
|
|
343
|
+
console.log('Remove requested:', e.detail.cartKey);
|
|
344
344
|
|
|
345
|
-
|
|
346
|
-
|
|
345
|
+
// The component handles the API calls automatically
|
|
346
|
+
// Just listen for the data changes
|
|
347
347
|
});
|
|
348
348
|
|
|
349
349
|
cartDialog.addEventListener('cart-item:quantity-change', (e) => {
|
|
350
|
-
|
|
351
|
-
|
|
350
|
+
console.log('Quantity changed:', e.detail.quantity);
|
|
351
|
+
// Component automatically syncs with Shopify
|
|
352
352
|
});
|
|
353
353
|
|
|
354
354
|
// Listen for all cart changes
|
|
355
355
|
cartDialog.on('cart-dialog:data-changed', (cartData) => {
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
356
|
+
// Update your UI when cart changes
|
|
357
|
+
updateCartBadge(cartData.item_count);
|
|
358
|
+
updateCartTotal(cartData.total_price);
|
|
359
359
|
});
|
|
360
360
|
```
|
|
361
361
|
|
|
@@ -377,81 +377,46 @@ The component is optimized for:
|
|
|
377
377
|
|
|
378
378
|
The cart panel automatically integrates with Shopify's AJAX Cart API. Simply add the component to your theme and it handles all cart operations:
|
|
379
379
|
|
|
380
|
-
```
|
|
380
|
+
```html
|
|
381
381
|
<!-- In your Shopify theme layout -->
|
|
382
382
|
<button
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
383
|
+
aria-haspopup="dialog"
|
|
384
|
+
aria-controls="shopify-cart"
|
|
385
|
+
aria-expanded="false"
|
|
386
|
+
class="cart-trigger">
|
|
387
|
+
Cart ({{ cart.item_count }})
|
|
388
388
|
</button>
|
|
389
389
|
|
|
390
390
|
<cart-dialog id="shopify-cart" aria-labelledby="cart-heading">
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
<div class="item-details">
|
|
407
|
-
<h4>{{ item.product.title }}</h4>
|
|
408
|
-
{% unless item.variant.title == 'Default Title' %}
|
|
409
|
-
<p class="variant">{{ item.variant.title }}</p>
|
|
410
|
-
{% endunless %}
|
|
411
|
-
<p class="price">{{ item.final_price | money }}</p>
|
|
412
|
-
</div>
|
|
413
|
-
<div class="item-controls">
|
|
414
|
-
<input
|
|
415
|
-
type="number"
|
|
416
|
-
data-cart-quantity
|
|
417
|
-
value="{{ item.quantity }}"
|
|
418
|
-
min="0">
|
|
419
|
-
<button data-action="remove">{{ 'cart.general.remove' | t }}</button>
|
|
420
|
-
</div>
|
|
421
|
-
</div>
|
|
422
|
-
</cart-item-content>
|
|
423
|
-
<cart-item-processing>
|
|
424
|
-
<div class="spinner"></div>
|
|
425
|
-
<span>{{ 'cart.general.updating' | t }}</span>
|
|
426
|
-
</cart-item-processing>
|
|
427
|
-
</cart-item>
|
|
428
|
-
{% endfor %}
|
|
429
|
-
</div>
|
|
430
|
-
|
|
431
|
-
<footer class="cart-footer">
|
|
432
|
-
<div class="cart-total">
|
|
433
|
-
{{ 'cart.general.total' | t }}: <span data-cart-total>{{ cart.total_price | money }}</span>
|
|
434
|
-
</div>
|
|
435
|
-
<a href="/checkout" class="checkout-btn">
|
|
436
|
-
{{ 'cart.general.checkout' | t }}
|
|
437
|
-
</a>
|
|
438
|
-
</footer>
|
|
439
|
-
</cart-panel>
|
|
391
|
+
<cart-panel>
|
|
392
|
+
<header class="cart-header">
|
|
393
|
+
<h2 id="cart-heading">Your Cart</h2>
|
|
394
|
+
<button data-action="hide-cart" aria-label="hide cart">X</button>
|
|
395
|
+
</header>
|
|
396
|
+
|
|
397
|
+
<div class="cart-content">
|
|
398
|
+
<!-- Cart items will be populated automatically in javascript -->
|
|
399
|
+
</div>
|
|
400
|
+
|
|
401
|
+
<footer class="cart-footer">
|
|
402
|
+
<div class="cart-total"></div>
|
|
403
|
+
<a href="/checkout" class="button"> Checkout </a>
|
|
404
|
+
</footer>
|
|
405
|
+
</cart-panel>
|
|
440
406
|
</cart-dialog>
|
|
441
407
|
|
|
442
408
|
<script>
|
|
443
|
-
// Optional: Listen for cart updates to sync with other UI elements
|
|
444
|
-
document.querySelector('cart-dialog').on('cart-dialog:data-changed', (cartData) => {
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
});
|
|
409
|
+
// Optional: Listen for cart updates to sync with other UI elements
|
|
410
|
+
document.querySelector('cart-dialog').on('cart-dialog:data-changed', (cartData) => {
|
|
411
|
+
// Update cart count in header
|
|
412
|
+
document.querySelector('.cart-trigger').textContent = `Cart (${cartData.item_count})`;
|
|
413
|
+
|
|
414
|
+
// Update cart total
|
|
415
|
+
document.querySelector('[data-cart-total]').textContent = new Intl.NumberFormat('en-US', {
|
|
416
|
+
style: 'currency',
|
|
417
|
+
currency: 'USD',
|
|
418
|
+
}).format(cartData.total_price / 100);
|
|
419
|
+
});
|
|
455
420
|
</script>
|
|
456
421
|
```
|
|
457
422
|
|
|
@@ -460,63 +425,63 @@ document.querySelector('cart-dialog').on('cart-dialog:data-changed', (cartData)
|
|
|
460
425
|
```javascript
|
|
461
426
|
// Example for non-Shopify platforms
|
|
462
427
|
class CustomCartManager {
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
428
|
+
constructor() {
|
|
429
|
+
this.cartDialog = document.querySelector('cart-dialog');
|
|
430
|
+
this.setupEventListeners();
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
setupEventListeners() {
|
|
434
|
+
// Listen for cart data changes
|
|
435
|
+
this.cartDialog.on('cart-dialog:data-changed', (cartData) => {
|
|
436
|
+
this.updateCartUI(cartData);
|
|
437
|
+
});
|
|
438
|
+
|
|
439
|
+
// Override default cart operations for custom API
|
|
440
|
+
this.cartDialog.getCart = this.customGetCart.bind(this);
|
|
441
|
+
this.cartDialog.updateCartItem = this.customUpdateCartItem.bind(this);
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
async customGetCart() {
|
|
445
|
+
try {
|
|
446
|
+
const response = await fetch('/api/cart');
|
|
447
|
+
return await response.json();
|
|
448
|
+
} catch (error) {
|
|
449
|
+
console.error('Failed to fetch cart:', error);
|
|
450
|
+
return { error: true, message: error.message };
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
async customUpdateCartItem(itemId, quantity) {
|
|
455
|
+
try {
|
|
456
|
+
const response = await fetch('/api/cart/update', {
|
|
457
|
+
method: 'POST',
|
|
458
|
+
headers: { 'Content-Type': 'application/json' },
|
|
459
|
+
body: JSON.stringify({ itemId, quantity }),
|
|
460
|
+
});
|
|
461
|
+
|
|
462
|
+
if (!response.ok) throw new Error(response.statusText);
|
|
463
|
+
|
|
464
|
+
// Return updated cart data
|
|
465
|
+
return this.customGetCart();
|
|
466
|
+
} catch (error) {
|
|
467
|
+
console.error('Failed to update cart:', error);
|
|
468
|
+
return { error: true, message: error.message };
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
updateCartUI(cartData) {
|
|
473
|
+
// Update cart count in navigation
|
|
474
|
+
const cartCount = document.querySelector('.cart-count');
|
|
475
|
+
if (cartCount) {
|
|
476
|
+
cartCount.textContent = cartData.items?.length || 0;
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
// Update cart total display
|
|
480
|
+
const cartTotal = document.querySelector('.cart-total-display');
|
|
481
|
+
if (cartTotal && cartData.total) {
|
|
482
|
+
cartTotal.textContent = cartData.total;
|
|
483
|
+
}
|
|
484
|
+
}
|
|
520
485
|
}
|
|
521
486
|
|
|
522
487
|
// Initialize
|
package/dist/cart-panel.cjs.css
CHANGED
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
cart-item {
|
|
2
2
|
--cart-item-processing-duration: 250ms;
|
|
3
3
|
--cart-item-destroying-duration: 600ms;
|
|
4
|
+
--cart-item-appearing-duration: 400ms;
|
|
4
5
|
--cart-item-shadow-color: rgba(0, 0, 0, 0.15);
|
|
5
6
|
--cart-item-shadow-color-strong: rgba(0, 0, 0, 0.5);
|
|
6
7
|
--cart-item-processing-bg: rgba(100, 100, 100, 0.2);
|
|
7
8
|
--cart-item-destroying-bg: rgba(0, 0, 0, 0.1);
|
|
8
9
|
--cart-item-processing-scale: 0.98;
|
|
9
10
|
--cart-item-destroying-scale: 0.85;
|
|
11
|
+
--cart-item-appearing-scale: 0.9;
|
|
10
12
|
--cart-item-processing-blur: 1px;
|
|
11
13
|
--cart-item-destroying-blur: 10px;
|
|
14
|
+
--cart-item-appearing-blur: 2px;
|
|
12
15
|
--cart-item-destroying-opacity: 0.2;
|
|
16
|
+
--cart-item-appearing-opacity: 0.5;
|
|
13
17
|
--cart-item-destroying-brightness: 0.6;
|
|
14
18
|
--cart-item-destroying-saturate: 0.3;
|
|
15
19
|
display: block;
|
|
@@ -31,53 +35,68 @@ cart-item::after {
|
|
|
31
35
|
left: 0px;
|
|
32
36
|
transition: background-color var(--cart-item-processing-duration) ease;
|
|
33
37
|
}
|
|
34
|
-
cart-item[
|
|
38
|
+
cart-item[state=ready] cart-item-content {
|
|
35
39
|
transform: scale(1);
|
|
36
40
|
filter: blur(0px);
|
|
37
41
|
opacity: 1;
|
|
38
42
|
}
|
|
39
|
-
cart-item[
|
|
43
|
+
cart-item[state=ready] cart-item-processing {
|
|
40
44
|
opacity: 0;
|
|
41
45
|
visibility: hidden;
|
|
42
46
|
}
|
|
43
|
-
cart-item[
|
|
47
|
+
cart-item[state=processing] {
|
|
44
48
|
box-shadow: inset 0px 2px 10px var(--cart-item-shadow-color);
|
|
45
49
|
}
|
|
46
|
-
cart-item[
|
|
50
|
+
cart-item[state=processing]::after {
|
|
47
51
|
background: rgba(0, 0, 0, 0.15);
|
|
48
52
|
}
|
|
49
|
-
cart-item[
|
|
53
|
+
cart-item[state=processing] cart-item-content {
|
|
50
54
|
transform: scale(var(--cart-item-processing-scale));
|
|
51
55
|
filter: blur(var(--cart-item-processing-blur));
|
|
52
56
|
opacity: 0.9;
|
|
53
57
|
pointer-events: none;
|
|
54
58
|
}
|
|
55
|
-
cart-item[
|
|
59
|
+
cart-item[state=processing] cart-item-processing {
|
|
56
60
|
opacity: 1;
|
|
57
61
|
visibility: visible;
|
|
58
62
|
}
|
|
59
|
-
cart-item[
|
|
63
|
+
cart-item[state=destroying] {
|
|
60
64
|
background-color: var(--cart-item-destroying-bg);
|
|
61
65
|
box-shadow: inset 0px 4px 20px var(--cart-item-shadow-color-strong);
|
|
62
66
|
margin-top: 0px;
|
|
63
67
|
margin-bottom: 0px;
|
|
64
68
|
transition: filter var(--cart-item-destroying-duration) ease, background-color var(--cart-item-destroying-duration) ease, box-shadow var(--cart-item-destroying-duration) ease, margin var(--cart-item-destroying-duration) ease;
|
|
65
69
|
}
|
|
66
|
-
cart-item[
|
|
70
|
+
cart-item[state=destroying]::after {
|
|
67
71
|
background: rgba(0, 0, 0, 0.9);
|
|
68
72
|
transition: background-color var(--cart-item-destroying-duration) ease;
|
|
69
73
|
}
|
|
70
|
-
cart-item[
|
|
74
|
+
cart-item[state=destroying] cart-item-content {
|
|
71
75
|
transition: transform var(--cart-item-destroying-duration) ease, filter var(--cart-item-destroying-duration) ease, opacity var(--cart-item-destroying-duration) ease;
|
|
72
76
|
transform: scale(var(--cart-item-destroying-scale));
|
|
73
77
|
filter: blur(var(--cart-item-destroying-blur)) saturate(var(--cart-item-destroying-saturate));
|
|
74
78
|
opacity: var(--cart-item-destroying-opacity);
|
|
75
79
|
pointer-events: none;
|
|
76
80
|
}
|
|
77
|
-
cart-item[
|
|
81
|
+
cart-item[state=destroying] cart-item-processing {
|
|
78
82
|
opacity: 0;
|
|
79
83
|
transition: opacity var(--cart-item-processing-duration) ease;
|
|
80
84
|
}
|
|
85
|
+
cart-item[state=appearing] {
|
|
86
|
+
height: 0px;
|
|
87
|
+
overflow: hidden;
|
|
88
|
+
transition: height var(--cart-item-appearing-duration) ease-out, filter var(--cart-item-appearing-duration) ease-out, opacity var(--cart-item-appearing-duration) ease-out;
|
|
89
|
+
}
|
|
90
|
+
cart-item[state=appearing] cart-item-content {
|
|
91
|
+
transform: scale(var(--cart-item-appearing-scale));
|
|
92
|
+
filter: blur(var(--cart-item-appearing-blur));
|
|
93
|
+
opacity: var(--cart-item-appearing-opacity);
|
|
94
|
+
transition: transform var(--cart-item-appearing-duration) ease-out, filter var(--cart-item-appearing-duration) ease-out, opacity var(--cart-item-appearing-duration) ease-out;
|
|
95
|
+
}
|
|
96
|
+
cart-item[state=appearing] cart-item-processing {
|
|
97
|
+
opacity: 0;
|
|
98
|
+
visibility: hidden;
|
|
99
|
+
}
|
|
81
100
|
|
|
82
101
|
cart-item-content {
|
|
83
102
|
display: block;
|
|
@@ -99,7 +118,29 @@ cart-item-processing {
|
|
|
99
118
|
transition: opacity var(--cart-item-processing-duration) ease-out, visibility var(--cart-item-processing-duration) ease-out;
|
|
100
119
|
z-index: 10;
|
|
101
120
|
}
|
|
121
|
+
cart-item-processing .cart-item-loader {
|
|
122
|
+
width: 60px;
|
|
123
|
+
aspect-ratio: 2;
|
|
124
|
+
--_g: no-repeat radial-gradient(circle closest-side, #000 90%, #0000);
|
|
125
|
+
background: var(--_g) 0% 50%, var(--_g) 50% 50%, var(--_g) 100% 50%;
|
|
126
|
+
background-size: 33.3333333333% 50%;
|
|
127
|
+
animation: cart-item-loader 1s infinite linear;
|
|
128
|
+
}
|
|
102
129
|
|
|
130
|
+
@keyframes cart-item-loader {
|
|
131
|
+
20% {
|
|
132
|
+
background-position: 0% 0%, 50% 50%, 100% 50%;
|
|
133
|
+
}
|
|
134
|
+
40% {
|
|
135
|
+
background-position: 0% 100%, 50% 0%, 100% 50%;
|
|
136
|
+
}
|
|
137
|
+
60% {
|
|
138
|
+
background-position: 0% 50%, 50% 100%, 100% 0%;
|
|
139
|
+
}
|
|
140
|
+
80% {
|
|
141
|
+
background-position: 0% 50%, 50% 50%, 100% 100%;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
103
144
|
:root {
|
|
104
145
|
--cart-dialog-z-index: 1000;
|
|
105
146
|
--cart-overlay-z-index: 1000;
|