Skip to content

Commit 42af33b

Browse files
committed
Merge remote-tracking branch 'upstream/master'
2 parents b6b5313 + 33d6aff commit 42af33b

33 files changed

+1394
-147
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,4 @@ _site
2121
.jekyll-metadata
2222
/test/build
2323
config.json
24+
/.vscode

CHANGELOG.md

+31-1
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,55 @@
11
# Changelog
22

3+
### v2.1.7 (July 13, 2020)
4+
5+
- Update product set component to use the correct container node when in non-iFrame mode [#680](https://github.com/Shopify/buy-button-js/pull/680)
6+
7+
### v2.1.6 (July 8, 2020)
8+
9+
- Fixed disabled button css class [#681](https://github.com/shopify/buy-button-js/pull/681)
10+
- Show discount code within the cart when discount title is unavailable [#686](https://github.com/Shopify/buy-button-js/pull/686)
11+
- Prevent adding multiple close modal event listeners [#692](https://github.com/shopify/buy-button-js/pull/692)
12+
13+
### v2.1.5 (July 7, 2020)
14+
15+
- Updated `JS Buy SDK` to `v2.11.0`, which uses Storefront API version [2020-07](https://shopify.dev/concepts/about-apis/versioning/release-notes/2020-07) ([#699](https://github.com/Shopify/buy-button-js/pull/699))
16+
17+
### v2.1.4 (July 7, 2020)
18+
19+
- Updated changelog for [v2.1.3](https://github.com/Shopify/buy-button-js/pull/685)
20+
321
### v2.1.3 (May 12, 2020)
22+
423
- Updated `JS Buy SDK` to `v2.10.0`, which uses Storefront API version [2020-04](https://shopify.dev/concepts/about-apis/versioning/release-notes/2020-04) ([#684](https://github.com/Shopify/buy-button-js/pull/684))
524

625
### v2.1.2 (April 6, 2020)
26+
727
- Updated code of conduct report link ([#678](https://github.com/Shopify/buy-button-js/pull/678))
828

929
### v2.1.1 (March 23, 2020)
30+
1031
- Updated `JS Buy SDK` to `v2.9.2` ([#674](https://github.com/Shopify/buy-button-js/pull/674))
1132
- This update ensures that checkouts and content returned from Storefront API/JS Buy SDK will be in the store's primary language.
1233

1334
### v2.1.0 (January 9, 2020)
35+
1436
- Add unit pricing to the product component ([#671](https://github.com/Shopify/buy-button-js/pull/671))
1537

1638
### v2.0.0 (November 19, 2019)
39+
1740
- Defer creation of checkout until a variant is added to cart ([#657](https://github.com/Shopify/buy-button-js/pull/657))
1841
- The cart component's model will now be null until a variant has been added to the cart
1942

2043
### v1.0.4 (October 9, 2019)
44+
2145
- Changed text-rendering to auto for select elements to prevent Safari 13 from crashing ([#653](https://github.com/Shopify/buy-button-js/pull/653))
2246

2347
### v1.0.3 (October 8, 2019)
48+
2449
- Fix product set's `trackingInfo` to return tracking information for each product in set ([#651](https://github.com/Shopify/buy-button-js/pull/651))
2550

2651
### v1.0.2 (September 24, 2019)
52+
2753
- Add `openCheckout` user event ([#647](https://github.com/Shopify/buy-button-js/pull/647))
2854
- Fixed pagination error for product set buy buttons ([#645](https://github.com/Shopify/buy-button-js/pull/645))
2955
- Tracker related updates:
@@ -32,16 +58,18 @@
3258
- Updated tracking info values and added addtional properties ([#645](https://github.com/Shopify/buy-button-js/pull/645))
3359

3460
### v1.0.1 (September 10, 2019)
61+
3562
- Fix how ShopifyBuy.UI is set ([#643](https://github.com/Shopify/buy-button-js/pull/643))
3663

3764
### v1.0.0 (September 5, 2019)
65+
3866
- Add support for automatic discounts in the `lineItem` component ([#640](https://github.com/Shopify/buy-button-js/pull/640))
3967
- Add `priceWithDiscounts` contents option and enable by default
4068
- Disable `price` contents option by default
4169
- Add `priceWithDiscounts` to the order array
4270
- Add `priceWithDiscounts`, `fullPrice`, `discount`, and `discountIcon` styles
4371
- Update default `price` styles to account for its position inside the `priceWithDiscounts` container
44-
- Add support for automatic discounts in the `cart` component ([#640](https://github.com/Shopify/buy-button-js/pull/640))
72+
- Add support for automatic discounts in the `cart` component ([#640](https://github.com/Shopify/buy-button-js/pull/640))
4573
- Add `discounts` contents option and enable by default
4674
- Add `discount`, `discountText`, `discountIcon`, `discountAmount`, and `cartScrollWithDiscounts` styles
4775
- Update layout of `lineItem` component to position variant title below product title ([#640](https://github.com/Shopify/buy-button-js/pull/640))
@@ -55,6 +83,7 @@
5583
- Android: 4.4+
5684

5785
### v0.12.0 (August 15, 2019)
86+
5887
- Bump various npm dependencies, notably the following major updates: ([#633](https://github.com/Shopify/buy-button-js/pull/633))
5988
- `babel/core` | `babel/cli` | `babel/runtime` : v7.x
6089
- `core-js`: v3.1.4
@@ -67,6 +96,7 @@
6796
- Fix missing double quotes around classes in options template ([#636](https://github.com/Shopify/buy-button-js/pull/636))
6897

6998
### v0.11.0 (March 29, 2019)
99+
70100
- Bump `shopify-buy` dependency to v2.2.0.
71101
- Asserts `lineItemsSubtotalPrice` is exposed.
72102
- Add a `formattedLineItemsSubtotal` field to cart view model. The new field consists in a sum of all line items prices without any discount, taxes or shipping rates applications.

package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@shopify/buy-button-js",
3-
"version": "2.1.3",
3+
"version": "2.1.7",
44
"browserslist": [
55
"last 2 Chrome versions",
66
"last 2 Firefox versions",
@@ -105,7 +105,7 @@
105105
"morphdom": "2.5.5",
106106
"mustache": "3.0.1",
107107
"node-sass": "4.12.0",
108-
"shopify-buy": "2.10.0",
108+
"shopify-buy": "2.11.0",
109109
"uglify-js": "3.6.0"
110110
}
111111
}

src/components/cart.js

+27-7
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import formatMoney from '../utils/money';
77
import CartView from '../views/cart';
88
import CartUpdater from '../updaters/cart';
99
import {addClassToElement} from '../utils/element-class';
10+
import {removeTrapFocus} from '../utils/focus';
1011

1112
export const NO_IMG_URL = '//sdks.shopifycdn.com/buy-button/latest/no-image.jpg';
1213

@@ -98,8 +99,9 @@ export default class Cart extends Component {
9899
const targetSelection = discount.discountApplication.targetSelection;
99100
if (LINE_ITEM_TARGET_SELECTIONS.indexOf(targetSelection) > -1) {
100101
const discountAmount = discount.allocatedAmount.amount;
102+
const discountDisplayText = discount.discountApplication.title || discount.discountApplication.code;
101103
discountAcc.totalDiscount += discountAmount;
102-
discountAcc.discounts.push({discount: `${discount.discountApplication.title} (-${formatMoney(discountAmount, this.moneyFormat)})`});
104+
discountAcc.discounts.push({discount: `${discountDisplayText} (-${formatMoney(discountAmount, this.moneyFormat)})`});
103105
}
104106
return discountAcc;
105107
}, {
@@ -112,9 +114,10 @@ export default class Cart extends Component {
112114
data.formattedPrice = formattedPrice;
113115

114116
data.classes = this.classes;
117+
data.text = this.config.lineItem.text;
115118
data.lineItemImage = this.imageForLineItem(data);
116119
data.variantTitle = data.variant.title === 'Default Title' ? '' : data.variant.title;
117-
return acc + this.childTemplate.render({data}, (output) => `<div id="${lineItem.id}" class=${this.classes.lineItem.lineItem}>${output}</div>`);
120+
return acc + this.childTemplate.render({data}, (output) => `<li id="${lineItem.id}" class=${this.classes.lineItem.lineItem}>${output}</li>`);
118121
}, '');
119122
}
120123

@@ -133,6 +136,7 @@ export default class Cart extends Component {
133136
discounts: this.cartDiscounts,
134137
contents: this.options.contents,
135138
cartNote: this.cartNote,
139+
cartNoteId: this.cartNoteId,
136140
});
137141
}
138142

@@ -163,7 +167,8 @@ export default class Cart extends Component {
163167
}
164168

165169
if (discountValue > 0) {
166-
discountArr.push({text: discount.title, amount: `-${formatMoney(discountValue, this.moneyFormat)}`});
170+
const discountDisplayText = discount.title || discount.code;
171+
discountArr.push({text: discountDisplayText, amount: `-${formatMoney(discountValue, this.moneyFormat)}`});
167172
}
168173
}
169174
return discountArr;
@@ -185,6 +190,10 @@ export default class Cart extends Component {
185190
return this.model && this.model.note;
186191
}
187192

193+
get cartNoteId() {
194+
return `CartNote-${Date.now()}`;
195+
}
196+
188197
get wrapperClass() {
189198
return this.isVisible ? 'is-active' : '';
190199
}
@@ -289,6 +298,7 @@ export default class Cart extends Component {
289298
close() {
290299
this.isVisible = false;
291300
this.view.render();
301+
removeTrapFocus(this.view.wrapper);
292302
}
293303

294304
/**
@@ -297,7 +307,7 @@ export default class Cart extends Component {
297307
open() {
298308
this.isVisible = true;
299309
this.view.render();
300-
this.view.setFocus();
310+
this.setFocus();
301311
}
302312

303313
/**
@@ -308,7 +318,7 @@ export default class Cart extends Component {
308318
this.isVisible = visible || !this.isVisible;
309319
this.view.render();
310320
if (this.isVisible) {
311-
this.view.setFocus();
321+
this.setFocus();
312322
}
313323
}
314324

@@ -424,7 +434,9 @@ export default class Cart extends Component {
424434
this.updateCache(this.model.lineItems);
425435
this.view.render();
426436
this.toggles.forEach((toggle) => toggle.view.render());
427-
this.view.setFocus();
437+
if (!openCart) {
438+
this.setFocus();
439+
}
428440
return checkout;
429441
});
430442
} else {
@@ -439,7 +451,9 @@ export default class Cart extends Component {
439451
this.updateCache(this.model.lineItems);
440452
this.view.render();
441453
this.toggles.forEach((toggle) => toggle.view.render());
442-
this.view.setFocus();
454+
if (!openCart) {
455+
this.setFocus();
456+
}
443457
return checkout;
444458
});
445459
}
@@ -475,4 +489,10 @@ export default class Cart extends Component {
475489
sku: null,
476490
};
477491
}
492+
493+
setFocus() {
494+
setTimeout(() => {
495+
this.view.setFocus();
496+
}, 0);
497+
}
478498
}

src/components/modal.js

+1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ export default class Modal extends Component {
4444
return Object.assign({}, this.globalConfig, {
4545
node: this.productWrapper,
4646
options: merge({}, this.config),
47+
modalProduct: true,
4748
});
4849
}
4950

src/components/product-set.js

+4
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,10 @@ export default class ProductSet extends Component {
225225
}),
226226
});
227227

228+
if (this.config.productSet.iframe === false) {
229+
productConfig.node = this.node.querySelector(`.${this.classes.productSet.products}`);
230+
}
231+
228232
const promises = this.model.products.map((productModel) => {
229233
const product = new Product(productConfig, this.props);
230234
this.products.push(product);

src/components/product.js

+22-5
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ export default class Product extends Component {
8282
this.selectedVariant = {};
8383
this.selectedOptions = {};
8484
this.selectedImage = null;
85+
this.modalProduct = Boolean(config.modalProduct);
8586
this.updater = new ProductUpdater(this);
8687
this.view = new ProductView(this);
8788
}
@@ -186,7 +187,7 @@ export default class Product extends Component {
186187
* @return {String}
187188
*/
188189
get formattedCompareAtPrice() {
189-
if (!this.selectedVariant || !this.selectedVariant.compareAtPriceV2) {
190+
if (!this.hasCompareAtPrice) {
190191
return '';
191192
}
192193
return formatMoney(this.selectedVariant.compareAtPriceV2.amount, this.globalConfig.moneyFormat);
@@ -252,7 +253,10 @@ export default class Product extends Component {
252253
quantityClass: this.quantityClass,
253254
priceClass: this.priceClass,
254255
formattedPrice: this.formattedPrice,
256+
priceAccessibilityLabel: this.priceAccessibilityLabel,
257+
hasCompareAtPrice: this.hasCompareAtPrice,
255258
formattedCompareAtPrice: this.formattedCompareAtPrice,
259+
compareAtPriceAccessibilityLabel: this.compareAtPriceAccessibilityLabel,
256260
showUnitPrice: this.showUnitPrice,
257261
formattedUnitPrice: this.formattedUnitPrice,
258262
formattedUnitPriceBaseUnit: this.formattedUnitPriceBaseUnit,
@@ -274,7 +278,7 @@ export default class Product extends Component {
274278
}
275279

276280
get buttonClass() {
277-
const disabledClass = this.buttonEnabled ? '' : this.classes.disabled;
281+
const disabledClass = this.buttonEnabled ? '' : this.classes.product.disabled;
278282
const quantityClass = this.options.contents.buttonWithQuantity ? this.classes.product.buttonBesideQty : '';
279283
return `${disabledClass} ${quantityClass}`;
280284
}
@@ -331,7 +335,7 @@ export default class Product extends Component {
331335
}
332336

333337
get priceClass() {
334-
return this.selectedVariant && this.selectedVariant.compareAtPriceV2 ? this.classes.product.loweredPrice : '';
338+
return this.hasCompareAtPrice ? this.classes.product.loweredPrice : '';
335339
}
336340

337341
get isButton() {
@@ -381,9 +385,11 @@ export default class Product extends Component {
381385
return '';
382386
}
383387

384-
return this.decoratedOptions.reduce((acc, option) => {
388+
const uniqueId = Date.now();
389+
return this.decoratedOptions.reduce((acc, option, index) => {
385390
const data = merge(option, this.options.viewData);
386391
data.classes = this.classes;
392+
data.selectId = `Option-${uniqueId}-${index}`;
387393
data.onlyOption = (this.model.options.length === 1);
388394
return acc + this.childTemplate.render({data});
389395
}, '');
@@ -646,7 +652,7 @@ export default class Product extends Component {
646652
this.props.closeModal();
647653
this._userEvent('addVariantToCart');
648654
this.props.tracker.trackMethod(this.cart.addVariantToCart.bind(this), 'Update Cart', this.selectedVariantTrackingInfo)(this.selectedVariant, this.selectedQuantity);
649-
if (this.iframe) {
655+
if (!this.modalProduct) {
650656
this.props.setActiveEl(target);
651657
}
652658
} else if (this.options.buttonDestination === 'modal') {
@@ -841,4 +847,15 @@ export default class Product extends Component {
841847
return altText || this.model.title;
842848
}
843849

850+
get priceAccessibilityLabel() {
851+
return this.hasCompareAtPrice ? this.options.text.salePriceAccessibilityLabel : this.options.text.regularPriceAccessibilityLabel;
852+
}
853+
854+
get compareAtPriceAccessibilityLabel() {
855+
return this.hasCompareAtPrice ? this.options.text.regularPriceAccessibilityLabel : '';
856+
}
857+
858+
get hasCompareAtPrice() {
859+
return Boolean(this.selectedVariant && this.selectedVariant.compareAtPriceV2);
860+
}
844861
}

src/components/toggle.js

+1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ export default class CartToggle extends Component {
3636

3737
toggleCart(evt) {
3838
evt.stopPropagation();
39+
this.props.setActiveEl(this.view.node);
3940
this.props.cart.toggleVisibility();
4041
}
4142
}

src/defaults/components.js

+8
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ const defaults = {
8282
unavailable: 'Unavailable',
8383
unitPriceAccessibilityLabel: 'Unit price',
8484
unitPriceAccessibilitySeparator: 'per',
85+
regularPriceAccessibilityLabel: 'Regular price',
86+
salePriceAccessibilityLabel: 'Sale price',
8587
},
8688
},
8789
modalProduct: {
@@ -237,6 +239,7 @@ const defaults = {
237239
currency: 'CAD',
238240
notice: 'Shipping and discount codes are added at checkout.',
239241
noteDescription: 'Special instructions for seller',
242+
closeAccessibilityLabel: 'Close cart',
240243
},
241244
},
242245
lineItem: {
@@ -276,6 +279,11 @@ const defaults = {
276279
quantityIncrement: 'shopify-buy__quantity-increment',
277280
quantityDecrement: 'shopify-buy__quantity-decrement',
278281
},
282+
text: {
283+
quantityInputAccessibilityLabel: 'Quantity',
284+
quantityDecrementAccessibilityLabel: 'Reduce item quantity by one',
285+
quantityIncrementAccessibilityLabel: 'Increase item quantity by one',
286+
},
279287
},
280288
toggle: {
281289
templates: toggleTemplates,

src/styles/embeds/sass/components/product.css

+1-1
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@
115115
font-size: 12px;
116116
text-decoration: line-through;
117117
padding-left: 5px;
118-
opacity: 0.65;
118+
opacity: 0.76;
119119
}
120120

121121
.shopify-buy__product__unit-price {

src/styles/embeds/sass/components/select.css

-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
box-sizing: border-box;
55
position: relative;
66
background: var(--color-white);
7-
overflow: hidden;
87
vertical-align: bottom;
98
}
109

0 commit comments

Comments
 (0)