fontdue-js 2.18.4 → 2.19.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.
Files changed (56) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/__generated__/AddToCartBannerQuery.graphql.d.ts +1 -1
  3. package/dist/__generated__/AddToCartBannerQuery.graphql.js +22 -7
  4. package/dist/__generated__/AddToCartBanner_item.graphql.d.ts +10 -1
  5. package/dist/__generated__/AddToCartBanner_item.graphql.js +19 -4
  6. package/dist/__generated__/AddToCartBanner_order.graphql.d.ts +10 -1
  7. package/dist/__generated__/AddToCartBanner_order.graphql.js +18 -3
  8. package/dist/__generated__/CartItemProduct_product.graphql.d.ts +4 -1
  9. package/dist/__generated__/CartItemProduct_product.graphql.js +15 -5
  10. package/dist/__generated__/CartOrderCompleteOrderMutation.graphql.d.ts +1 -1
  11. package/dist/__generated__/CartOrderCompleteOrderMutation.graphql.js +27 -5
  12. package/dist/__generated__/CartOrderRemoveDiscountMutation.graphql.d.ts +1 -1
  13. package/dist/__generated__/CartOrderRemoveDiscountMutation.graphql.js +27 -5
  14. package/dist/__generated__/CartOrderUpdateMutation.graphql.d.ts +1 -1
  15. package/dist/__generated__/CartOrderUpdateMutation.graphql.js +27 -5
  16. package/dist/__generated__/CartQuery.graphql.d.ts +1 -1
  17. package/dist/__generated__/CartQuery.graphql.js +27 -5
  18. package/dist/__generated__/CartStateRemoveDiscountMutation.graphql.d.ts +1 -1
  19. package/dist/__generated__/CartStateRemoveDiscountMutation.graphql.js +15 -3
  20. package/dist/__generated__/CartStateUpdateMutation.graphql.d.ts +1 -1
  21. package/dist/__generated__/CartStateUpdateMutation.graphql.js +27 -5
  22. package/dist/__generated__/CartTotals_order.graphql.d.ts +3 -1
  23. package/dist/__generated__/CartTotals_order.graphql.js +14 -2
  24. package/dist/__generated__/CheckoutUpdateCustomerMutation.graphql.d.ts +1 -1
  25. package/dist/__generated__/CheckoutUpdateCustomerMutation.graphql.js +27 -5
  26. package/dist/__generated__/CheckoutUpdateOrderMutation.graphql.d.ts +1 -1
  27. package/dist/__generated__/CheckoutUpdateOrderMutation.graphql.js +27 -5
  28. package/dist/__generated__/CouponCodeInputApplyCouponMutation.graphql.d.ts +1 -1
  29. package/dist/__generated__/CouponCodeInputApplyCouponMutation.graphql.js +15 -3
  30. package/dist/__generated__/PrecartAddToCartMutation.graphql.d.ts +1 -1
  31. package/dist/__generated__/PrecartAddToCartMutation.graphql.js +32 -10
  32. package/dist/__generated__/StoreModalCartQuery.graphql.d.ts +1 -1
  33. package/dist/__generated__/StoreModalCartQuery.graphql.js +38 -16
  34. package/dist/__generated__/StoreModalFamily_collection.graphql.d.ts +2 -1
  35. package/dist/__generated__/StoreModalFamily_collection.graphql.js +9 -3
  36. package/dist/__generated__/StoreModalProductQuery.graphql.d.ts +1 -1
  37. package/dist/__generated__/StoreModalProductQuery.graphql.js +10 -4
  38. package/dist/__generated__/StoreModalProductRefetchQuery.graphql.d.ts +1 -1
  39. package/dist/__generated__/StoreModalProductRefetchQuery.graphql.js +10 -4
  40. package/dist/__generated__/StoreModalUnifiedCheckoutUpdateOrderMutation.graphql.d.ts +1 -1
  41. package/dist/__generated__/StoreModalUnifiedCheckoutUpdateOrderMutation.graphql.js +15 -3
  42. package/dist/__generated__/TestFontsFormUpdateCustomerMutation.graphql.d.ts +1 -1
  43. package/dist/__generated__/TestFontsFormUpdateCustomerMutation.graphql.js +27 -5
  44. package/dist/components/AddToCartBanner/index.js +7 -1
  45. package/dist/components/Cart/CartItem/CartItemProduct.js +3 -2
  46. package/dist/components/Cart/CartTotals.js +7 -7
  47. package/dist/components/CharacterViewer/index.js +53 -37
  48. package/dist/components/CorsErrorModal.d.ts +1 -0
  49. package/dist/components/CorsErrorModal.js +99 -0
  50. package/dist/components/OrderVariableSelection/OrderVariableSelectionRedux.js +2 -1
  51. package/dist/components/StoreModal/StoreModalFamily.js +2 -2
  52. package/dist/corsError.d.ts +5 -0
  53. package/dist/corsError.js +55 -0
  54. package/dist/fontdue.css +5 -1
  55. package/dist/relay/environment.js +33 -19
  56. package/package.json +1 -1
@@ -5,7 +5,7 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.default = void 0;
7
7
  /**
8
- * @generated SignedSource<<7fdadb278562d0302596d82154638f19>>
8
+ * @generated SignedSource<<b5e73bb32d6eedb41863a2e3407b91ad>>
9
9
  * @lightSyntaxTransform
10
10
  * @nogrep
11
11
  */
@@ -168,6 +168,16 @@ const node = function () {
168
168
  "kind": "ScalarField",
169
169
  "name": "totalStyles",
170
170
  "storageKey": null
171
+ },
172
+ v14 = {
173
+ "alias": null,
174
+ "args": null,
175
+ "concreteType": "FontCollection",
176
+ "kind": "LinkedField",
177
+ "name": "fontCollection",
178
+ "plural": false,
179
+ "selections": [v2 /*: any*/, v4 /*: any*/],
180
+ "storageKey": null
171
181
  };
172
182
  return {
173
183
  "fragment": {
@@ -388,6 +398,18 @@ const node = function () {
388
398
  "kind": "ScalarField",
389
399
  "name": "taxName",
390
400
  "storageKey": null
401
+ }, {
402
+ "alias": null,
403
+ "args": null,
404
+ "kind": "ScalarField",
405
+ "name": "taxNotApplicable",
406
+ "storageKey": null
407
+ }, {
408
+ "alias": null,
409
+ "args": null,
410
+ "kind": "ScalarField",
411
+ "name": "taxNotApplicableReason",
412
+ "storageKey": null
391
413
  }, {
392
414
  "alias": null,
393
415
  "args": null,
@@ -542,7 +564,7 @@ const node = function () {
542
564
  "plural": true,
543
565
  "selections": [v11 /*: any*/, v2 /*: any*/, v4 /*: any*/],
544
566
  "storageKey": null
545
- }, v2 /*: any*/],
567
+ }, v2 /*: any*/, v14 /*: any*/],
546
568
  "type": "Bundle",
547
569
  "abstractKey": null
548
570
  }, {
@@ -570,7 +592,7 @@ const node = function () {
570
592
  "abstractKey": null
571
593
  }, {
572
594
  "kind": "InlineFragment",
573
- "selections": [v2 /*: any*/, v13 /*: any*/],
595
+ "selections": [v2 /*: any*/, v13 /*: any*/, v14 /*: any*/],
574
596
  "type": "CollectionBundle",
575
597
  "abstractKey": null
576
598
  }, {
@@ -692,12 +714,12 @@ const node = function () {
692
714
  }]
693
715
  },
694
716
  "params": {
695
- "cacheID": "b284cc8ceb665cc1bd54161535f2607d",
717
+ "cacheID": "2bbcb1b9a68cd57c7fbd0e57bb5697b4",
696
718
  "id": null,
697
719
  "metadata": {},
698
720
  "name": "TestFontsFormUpdateCustomerMutation",
699
721
  "operationKind": "mutation",
700
- "text": "mutation TestFontsFormUpdateCustomerMutation(\n $input: UpdateCustomerInput!\n) {\n updateCustomer(input: $input) {\n order {\n ...CartOrder_order\n id\n }\n }\n}\n\nfragment CartItemAdditionalLicenses_licenses on License {\n id\n name\n}\n\nfragment CartItemAdditionalLicenses_orderItem on OrderItem {\n licenseSelections {\n license {\n id\n }\n id\n }\n}\n\nfragment CartItemLicense_selection on LicenseSelection {\n id\n license {\n id\n name\n licenseVariables {\n id\n ...CartItemVariable_variable\n }\n }\n licenseVariable {\n id\n }\n ...CartItemVariable_selection\n}\n\nfragment CartItemProduct_product on SkuProduct {\n __isSkuProduct: __typename\n __typename\n ...CollectionAa_product\n ...FontStyle_fontStyle\n ... on FontStyle {\n family {\n name\n cssUrl\n id\n }\n name\n variableInstances {\n name\n }\n }\n ... on Bundle {\n name\n }\n ... on FontCollection {\n name\n isVariableFont\n totalStyles\n featureStyle {\n family {\n cssUrl\n id\n }\n id\n }\n }\n ... on CollectionBundle {\n name\n totalStyles\n }\n}\n\nfragment CartItemVariable_selection on LicenseSelection {\n id\n variableText\n license {\n id\n }\n licenseVariable {\n ...VariableTableAmounts_variable\n id\n name\n variableType\n licenseOptions {\n id\n }\n }\n licenseOption {\n ...VariableTableAmounts_option\n id\n name\n amount\n }\n}\n\nfragment CartItemVariable_variable on LicenseVariable {\n id\n licenseOptions {\n id\n name\n amount\n }\n}\n\nfragment CartItem_node on OrderItem {\n ...CartItemAdditionalLicenses_orderItem\n id\n price {\n ...Price_price\n }\n sku {\n price {\n ...Price_price\n }\n product {\n ...CartItemProduct_product\n __typename\n ... on Licenseable {\n __isLicenseable: __typename\n licenses {\n ...CartItemAdditionalLicenses_licenses\n id\n licenseVariables {\n id\n licenseOptions {\n id\n }\n }\n }\n }\n ... on Node {\n __isNode: __typename\n id\n }\n }\n id\n }\n licenseSelections {\n ...CartItemLicense_selection\n id\n license {\n id\n }\n licenseVariable {\n id\n }\n licenseOption {\n id\n }\n variableText\n }\n}\n\nfragment CartOrder_order on Order {\n ...Checkout_order\n ...Download_order\n ...CartTotals_order\n ...CartState_order\n id\n orderItems {\n ...CartItem_node\n id\n licenseSelections {\n license {\n id\n }\n licenseVariable {\n id\n variableType\n }\n licenseOption {\n id\n }\n variableText\n id\n }\n }\n orderVariableSelections {\n orderVariable {\n id\n }\n orderVariableOption {\n id\n }\n id\n }\n discount {\n id\n }\n customer {\n email\n name\n anonymous\n id\n }\n billingIdentity {\n ...IdentityBox_identity\n }\n licenseeIdentity {\n ...IdentityBox_identity\n }\n licenseeIsBillingIdentity\n stripePaymentMethod {\n card {\n last4\n brand\n }\n }\n stripePaymentIntent {\n status\n }\n canCompleteWithCoupon\n completedWithCoupon\n}\n\nfragment CartState_order on Order {\n id\n orderItems {\n id\n licenseSelections {\n license {\n id\n }\n licenseVariable {\n id\n }\n licenseOption {\n id\n }\n variableText\n id\n }\n }\n orderVariableSelections {\n orderVariable {\n id\n }\n orderVariableOption {\n id\n }\n countryCode\n id\n }\n}\n\nfragment CartTotals_order on Order {\n subtotal {\n ...Price_price\n }\n discount {\n amount {\n amount\n ...Price_price\n }\n coupon {\n ...CouponText_coupon\n id\n }\n id\n }\n discountedSubtotal {\n ...Price_price\n }\n total {\n amount\n ...Price_price\n }\n taxRate\n taxes {\n ...Price_price\n }\n taxName\n gstIncluded\n}\n\nfragment Checkout_order on Order {\n canCompleteWithCoupon\n customer {\n name\n email\n newsletterOptIn\n id\n }\n billingIdentity {\n name\n organization\n email\n phoneNullable\n street\n locality\n sublocality\n country\n administrativeArea\n zip\n vatNumber\n }\n licenseeIdentity {\n name\n organization\n email\n phoneNullable\n street\n locality\n sublocality\n country\n administrativeArea\n zip\n vatNumber\n }\n licenseeIsBillingIdentity\n}\n\nfragment CollectionAa_product on SkuProduct {\n __isSkuProduct: __typename\n __typename\n ... on FontCollection {\n featureStyle {\n ...FontStyle_fontStyle\n id\n }\n }\n ... on Bundle {\n fontStyles {\n ...FontStyle_fontStyle\n id\n }\n }\n}\n\nfragment CouponText_coupon on Coupon {\n type\n percentAmount\n creditAmount {\n amount\n currency\n }\n creditAmountRemaining {\n amount\n currency\n }\n}\n\nfragment Download_order on Order {\n id\n archiveUrl\n customer {\n email\n id\n }\n completedWithCoupon\n}\n\nfragment FontStyle_fontStyle on FontStyle {\n cssFamily\n name\n}\n\nfragment IdentityBox_identity on Identity {\n email\n phoneFormatted\n addressFormatted\n vatNumber\n}\n\nfragment Price_price on Money {\n amount\n currency\n}\n\nfragment VariableTableAmounts_option on LicenseOption {\n amounts\n}\n\nfragment VariableTableAmounts_variable on LicenseVariable {\n units\n}\n"
722
+ "text": "mutation TestFontsFormUpdateCustomerMutation(\n $input: UpdateCustomerInput!\n) {\n updateCustomer(input: $input) {\n order {\n ...CartOrder_order\n id\n }\n }\n}\n\nfragment CartItemAdditionalLicenses_licenses on License {\n id\n name\n}\n\nfragment CartItemAdditionalLicenses_orderItem on OrderItem {\n licenseSelections {\n license {\n id\n }\n id\n }\n}\n\nfragment CartItemLicense_selection on LicenseSelection {\n id\n license {\n id\n name\n licenseVariables {\n id\n ...CartItemVariable_variable\n }\n }\n licenseVariable {\n id\n }\n ...CartItemVariable_selection\n}\n\nfragment CartItemProduct_product on SkuProduct {\n __isSkuProduct: __typename\n __typename\n ...CollectionAa_product\n ...FontStyle_fontStyle\n ... on FontStyle {\n family {\n name\n cssUrl\n id\n }\n name\n variableInstances {\n name\n }\n }\n ... on Bundle {\n name\n fontCollection {\n name\n id\n }\n }\n ... on FontCollection {\n name\n isVariableFont\n totalStyles\n featureStyle {\n family {\n cssUrl\n id\n }\n id\n }\n }\n ... on CollectionBundle {\n name\n totalStyles\n fontCollection {\n name\n id\n }\n }\n}\n\nfragment CartItemVariable_selection on LicenseSelection {\n id\n variableText\n license {\n id\n }\n licenseVariable {\n ...VariableTableAmounts_variable\n id\n name\n variableType\n licenseOptions {\n id\n }\n }\n licenseOption {\n ...VariableTableAmounts_option\n id\n name\n amount\n }\n}\n\nfragment CartItemVariable_variable on LicenseVariable {\n id\n licenseOptions {\n id\n name\n amount\n }\n}\n\nfragment CartItem_node on OrderItem {\n ...CartItemAdditionalLicenses_orderItem\n id\n price {\n ...Price_price\n }\n sku {\n price {\n ...Price_price\n }\n product {\n ...CartItemProduct_product\n __typename\n ... on Licenseable {\n __isLicenseable: __typename\n licenses {\n ...CartItemAdditionalLicenses_licenses\n id\n licenseVariables {\n id\n licenseOptions {\n id\n }\n }\n }\n }\n ... on Node {\n __isNode: __typename\n id\n }\n }\n id\n }\n licenseSelections {\n ...CartItemLicense_selection\n id\n license {\n id\n }\n licenseVariable {\n id\n }\n licenseOption {\n id\n }\n variableText\n }\n}\n\nfragment CartOrder_order on Order {\n ...Checkout_order\n ...Download_order\n ...CartTotals_order\n ...CartState_order\n id\n orderItems {\n ...CartItem_node\n id\n licenseSelections {\n license {\n id\n }\n licenseVariable {\n id\n variableType\n }\n licenseOption {\n id\n }\n variableText\n id\n }\n }\n orderVariableSelections {\n orderVariable {\n id\n }\n orderVariableOption {\n id\n }\n id\n }\n discount {\n id\n }\n customer {\n email\n name\n anonymous\n id\n }\n billingIdentity {\n ...IdentityBox_identity\n }\n licenseeIdentity {\n ...IdentityBox_identity\n }\n licenseeIsBillingIdentity\n stripePaymentMethod {\n card {\n last4\n brand\n }\n }\n stripePaymentIntent {\n status\n }\n canCompleteWithCoupon\n completedWithCoupon\n}\n\nfragment CartState_order on Order {\n id\n orderItems {\n id\n licenseSelections {\n license {\n id\n }\n licenseVariable {\n id\n }\n licenseOption {\n id\n }\n variableText\n id\n }\n }\n orderVariableSelections {\n orderVariable {\n id\n }\n orderVariableOption {\n id\n }\n countryCode\n id\n }\n}\n\nfragment CartTotals_order on Order {\n subtotal {\n ...Price_price\n }\n discount {\n amount {\n amount\n ...Price_price\n }\n coupon {\n ...CouponText_coupon\n id\n }\n id\n }\n discountedSubtotal {\n ...Price_price\n }\n total {\n amount\n ...Price_price\n }\n taxRate\n taxes {\n ...Price_price\n }\n taxName\n taxNotApplicable\n taxNotApplicableReason\n gstIncluded\n}\n\nfragment Checkout_order on Order {\n canCompleteWithCoupon\n customer {\n name\n email\n newsletterOptIn\n id\n }\n billingIdentity {\n name\n organization\n email\n phoneNullable\n street\n locality\n sublocality\n country\n administrativeArea\n zip\n vatNumber\n }\n licenseeIdentity {\n name\n organization\n email\n phoneNullable\n street\n locality\n sublocality\n country\n administrativeArea\n zip\n vatNumber\n }\n licenseeIsBillingIdentity\n}\n\nfragment CollectionAa_product on SkuProduct {\n __isSkuProduct: __typename\n __typename\n ... on FontCollection {\n featureStyle {\n ...FontStyle_fontStyle\n id\n }\n }\n ... on Bundle {\n fontStyles {\n ...FontStyle_fontStyle\n id\n }\n }\n}\n\nfragment CouponText_coupon on Coupon {\n type\n percentAmount\n creditAmount {\n amount\n currency\n }\n creditAmountRemaining {\n amount\n currency\n }\n}\n\nfragment Download_order on Order {\n id\n archiveUrl\n customer {\n email\n id\n }\n completedWithCoupon\n}\n\nfragment FontStyle_fontStyle on FontStyle {\n cssFamily\n name\n}\n\nfragment IdentityBox_identity on Identity {\n email\n phoneFormatted\n addressFormatted\n vatNumber\n}\n\nfragment Price_price on Money {\n amount\n currency\n}\n\nfragment VariableTableAmounts_option on LicenseOption {\n amounts\n}\n\nfragment VariableTableAmounts_variable on LicenseVariable {\n units\n}\n"
701
723
  }
702
724
  };
703
725
  }();
@@ -21,10 +21,16 @@ const getOrderItemName = item => {
21
21
  var _product$family;
22
22
  return `${(_product$family = product.family) === null || _product$family === void 0 ? void 0 : _product$family.name} ${product.name}`;
23
23
  }
24
+ if (product.__typename === 'Bundle' || product.__typename === 'CollectionBundle') {
25
+ var _product$fontCollecti;
26
+ const familyName = (_product$fontCollecti = product.fontCollection) === null || _product$fontCollecti === void 0 ? void 0 : _product$fontCollecti.name;
27
+ if (familyName && !product.name.startsWith(familyName)) return `${familyName} ${product.name}`;
28
+ return product.name;
29
+ }
24
30
  if ('name' in product) return product.name;
25
31
  return null;
26
32
  };
27
- _AddToCartBanner_item2.default.hash && _AddToCartBanner_item2.default.hash !== "ebcfac33759865770c15e1efe0777e91" && console.error("The definition of 'AddToCartBanner_item' appears to have changed. Run `relay-compiler` to update the generated files to receive the expected data."), _AddToCartBanner_item2.default;
33
+ _AddToCartBanner_item2.default.hash && _AddToCartBanner_item2.default.hash !== "93905c08206c30255368dbb06f59ccec" && console.error("The definition of 'AddToCartBanner_item' appears to have changed. Run `relay-compiler` to update the generated files to receive the expected data."), _AddToCartBanner_item2.default;
28
34
  function AddToCartBanner(_ref) {
29
35
  var _order$orderItems, _order$orderItems2;
30
36
  let {
@@ -13,16 +13,17 @@ var _reactRelay = require("react-relay");
13
13
  var _utils = require("../../../utils");
14
14
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
15
15
  function CartItemProduct(_ref) {
16
- var _product$family, _product$featureStyle, _product$featureStyle2, _product$variableInst;
16
+ var _product$family, _product$featureStyle, _product$featureStyle2, _product$name, _product$variableInst;
17
17
  let {
18
18
  product: productKey
19
19
  } = _ref;
20
- const product = (0, _reactRelay.useFragment)((_CartItemProduct_product2.default.hash && _CartItemProduct_product2.default.hash !== "22f49bcb8a461d2d3eefc4f8ba1e575c" && console.error("The definition of 'CartItemProduct_product' appears to have changed. Run `relay-compiler` to update the generated files to receive the expected data."), _CartItemProduct_product2.default), productKey);
20
+ const product = (0, _reactRelay.useFragment)((_CartItemProduct_product2.default.hash && _CartItemProduct_product2.default.hash !== "b28cd421e634ecb1162252d953233456" && console.error("The definition of 'CartItemProduct_product' appears to have changed. Run `relay-compiler` to update the generated files to receive the expected data."), _CartItemProduct_product2.default), productKey);
21
21
  let productCss;
22
22
  if ((product === null || product === void 0 ? void 0 : product.__typename) === 'FontStyle') productCss = (_product$family = product.family) === null || _product$family === void 0 ? void 0 : _product$family.cssUrl;
23
23
  if ((product === null || product === void 0 ? void 0 : product.__typename) === 'FontCollection') productCss = (_product$featureStyle = product.featureStyle) === null || _product$featureStyle === void 0 ? void 0 : (_product$featureStyle2 = _product$featureStyle.family) === null || _product$featureStyle2 === void 0 ? void 0 : _product$featureStyle2.cssUrl;
24
24
  let productName = (product === null || product === void 0 ? void 0 : product.name) ?? '??';
25
25
  if ((product === null || product === void 0 ? void 0 : product.__typename) === 'FontStyle' && product.family) productName = `${product.family.name} ${product.name}`;
26
+ if (((product === null || product === void 0 ? void 0 : product.__typename) === 'Bundle' || (product === null || product === void 0 ? void 0 : product.__typename) === 'CollectionBundle') && product.fontCollection && !((_product$name = product.name) !== null && _product$name !== void 0 && _product$name.startsWith(product.fontCollection.name))) productName = `${product.fontCollection.name} ${product.name}`;
26
27
  return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("div", {
27
28
  className: "cart-item__aa"
28
29
  }, product ? /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_Stylesheet.default, {
@@ -45,7 +45,7 @@ function CartTotals(_ref2) {
45
45
  billingIdentity,
46
46
  taxSystem
47
47
  } = _ref2;
48
- const order = (0, _reactRelay.useFragment)((_CartTotals_order2.default.hash && _CartTotals_order2.default.hash !== "7fe25d7e214b579ce085157b9bd551a8" && console.error("The definition of 'CartTotals_order' appears to have changed. Run `relay-compiler` to update the generated files to receive the expected data."), _CartTotals_order2.default), orderKey);
48
+ const order = (0, _reactRelay.useFragment)((_CartTotals_order2.default.hash && _CartTotals_order2.default.hash !== "aee2e882d4d0d063fd4eaf6cb43485db" && console.error("The definition of 'CartTotals_order' appears to have changed. Run `relay-compiler` to update the generated files to receive the expected data."), _CartTotals_order2.default), orderKey);
49
49
  return /*#__PURE__*/_react.default.createElement("div", {
50
50
  className: "cart__price-blocks",
51
51
  "data-has-discount": Boolean(order.discount)
@@ -73,20 +73,20 @@ function CartTotals(_ref2) {
73
73
  label: "Discounted subtotal",
74
74
  price: order.discountedSubtotal,
75
75
  "data-line": "discounted-subtotal"
76
- })), /*#__PURE__*/_react.default.createElement("div", {
76
+ })), taxSystem !== 'none' && /*#__PURE__*/_react.default.createElement("div", {
77
77
  className: "cart__price-block",
78
78
  "data-line": "taxes"
79
79
  }, /*#__PURE__*/_react.default.createElement("div", {
80
80
  className: "cart__price-block__label"
81
- }, order.taxes && order.taxName ? `${order.taxName} (${percentage(order.taxRate)})` : 'Tax'), /*#__PURE__*/_react.default.createElement("div", {
81
+ }, order.taxNotApplicable ? /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, order.taxName ?? 'VAT', " not applicable", order.taxNotApplicableReason && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("br", null), /*#__PURE__*/_react.default.createElement("span", {
82
+ className: "cart__price-block__placeholder"
83
+ }, order.taxNotApplicableReason))) : order.taxes && order.taxName ? `${order.taxName} (${percentage(order.taxRate)})` : 'Tax'), /*#__PURE__*/_react.default.createElement("div", {
82
84
  className: "cart__price-block__price"
83
85
  }, order.taxes ? /*#__PURE__*/_react.default.createElement(_Price.default, {
84
86
  price: order.taxes
85
- }) : taxSystem === 'stripe' ? /*#__PURE__*/_react.default.createElement("span", {
86
- className: "cart__price-block__placeholder"
87
- }, "Calculated at checkout") : taxSystem === 'fontdue' && !billingIdentity ? /*#__PURE__*/_react.default.createElement("span", {
87
+ }) : taxSystem === 'stripe' || taxSystem === 'fontdue' && !billingIdentity ? /*#__PURE__*/_react.default.createElement("span", {
88
88
  className: "cart__price-block__placeholder"
89
- }, "Enter billing address") : '-')), /*#__PURE__*/_react.default.createElement("div", {
89
+ }, "Calculated at checkout") : '-')), /*#__PURE__*/_react.default.createElement("div", {
90
90
  className: "cart__price-block",
91
91
  "data-line": "total"
92
92
  }, /*#__PURE__*/_react.default.createElement("div", {
@@ -246,42 +246,50 @@ function CharacterViewerComponent(_ref3) {
246
246
  width: monitorWidth
247
247
  } = useSize();
248
248
  if (!fontStyle) return null;
249
- const lines = /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("div", {
250
- className: "character-viewer__monitor__line",
251
- "data-name": "baseline"
252
- }, /*#__PURE__*/_react.default.createElement("span", {
253
- className: "character-viewer__monitor__line__label"
254
- }, "Baseline"), /*#__PURE__*/_react.default.createElement("span", {
255
- className: "character-viewer__monitor__line__value"
256
- }, "0")), /*#__PURE__*/_react.default.createElement("div", {
257
- className: "character-viewer__monitor__line",
258
- "data-name": "descender"
259
- }, /*#__PURE__*/_react.default.createElement("span", {
260
- className: "character-viewer__monitor__line__label"
261
- }, "Descender"), /*#__PURE__*/_react.default.createElement("span", {
262
- className: "character-viewer__monitor__line__value"
263
- }, fontStyle.verticalMetrics.descender)), /*#__PURE__*/_react.default.createElement("div", {
264
- className: "character-viewer__monitor__line",
265
- "data-name": "ascender"
266
- }, /*#__PURE__*/_react.default.createElement("span", {
267
- className: "character-viewer__monitor__line__label"
268
- }, "Ascender"), /*#__PURE__*/_react.default.createElement("span", {
269
- className: "character-viewer__monitor__line__value"
270
- }, fontStyle.verticalMetrics.ascender)), fontStyle.verticalMetrics.capHeight && /*#__PURE__*/_react.default.createElement("div", {
271
- className: "character-viewer__monitor__line",
272
- "data-name": "cap-height"
273
- }, /*#__PURE__*/_react.default.createElement("span", {
274
- className: "character-viewer__monitor__line__label"
275
- }, "Cap height"), /*#__PURE__*/_react.default.createElement("span", {
276
- className: "character-viewer__monitor__line__value"
277
- }, fontStyle.verticalMetrics.capHeight)), fontStyle.verticalMetrics.xHeight && /*#__PURE__*/_react.default.createElement("div", {
278
- className: "character-viewer__monitor__line",
279
- "data-name": "x-height"
280
- }, /*#__PURE__*/_react.default.createElement("span", {
281
- className: "character-viewer__monitor__line__label"
282
- }, "x-Height"), /*#__PURE__*/_react.default.createElement("span", {
283
- className: "character-viewer__monitor__line__value"
284
- }, fontStyle.verticalMetrics.xHeight)));
249
+ const {
250
+ ascender,
251
+ descender,
252
+ capHeight,
253
+ xHeight,
254
+ lineGap,
255
+ unitsPerEm
256
+ } = fontStyle.verticalMetrics;
257
+ const halfGap = (lineGap ?? 0) / 2;
258
+ const pos = offset => ascender + halfGap - offset;
259
+
260
+ // Lines in priority order — lower-priority lines hidden when overlapping higher ones.
261
+ // Threshold: ~18px (label height) converted to font units via current scale.
262
+ const scale = monitorWidth ? monitorWidth / 2 / unitsPerEm : 0;
263
+ const threshold = scale > 0 ? 18 / scale : 0;
264
+ const lines = [{
265
+ name: 'baseline',
266
+ position: pos(0),
267
+ label: 'Baseline',
268
+ value: 0
269
+ }, capHeight != null && {
270
+ name: 'cap-height',
271
+ position: pos(capHeight),
272
+ label: 'Cap height',
273
+ value: capHeight
274
+ }, xHeight != null && {
275
+ name: 'x-height',
276
+ position: pos(xHeight),
277
+ label: 'x-Height',
278
+ value: xHeight
279
+ }, {
280
+ name: 'ascender',
281
+ position: pos(ascender),
282
+ label: 'Ascender',
283
+ value: ascender
284
+ }, {
285
+ name: 'descender',
286
+ position: pos(descender),
287
+ label: 'Descender',
288
+ value: descender
289
+ }].filter(line => Boolean(line)).reduce((visible, line) =>
290
+ // Skip this line if it's within the threshold of any already-accepted
291
+ // higher-priority line — otherwise accept it
292
+ threshold > 0 && visible.some(v => Math.abs(v.position - line.position) < threshold) ? visible : [...visible, line], []);
285
293
  const groups = (0, _react.useMemo)(() => {
286
294
  var _collection$glyphGrou;
287
295
  return (_collection$glyphGrou = collection.glyphGroups) === null || _collection$glyphGrou === void 0 ? void 0 : _collection$glyphGrou.map(_ref5 => {
@@ -336,7 +344,15 @@ function CharacterViewerComponent(_ref3) {
336
344
  fontFeatureSettings: visibleGlyph.features && featuresChecked ? `${visibleGlyph.features.map(feature => `'${feature}' 1`).join(', ')}` : `'calt' off, 'liga' off`
337
345
  },
338
346
  ref: monitorRef
339
- }, /*#__PURE__*/_react.default.createElement("span", null, visibleGlyph.string)), lines), /*#__PURE__*/_react.default.createElement("div", {
347
+ }, /*#__PURE__*/_react.default.createElement("span", null, visibleGlyph.string)), lines.map(line => /*#__PURE__*/_react.default.createElement("div", {
348
+ className: "character-viewer__monitor__line",
349
+ "data-name": line.name,
350
+ key: line.name
351
+ }, /*#__PURE__*/_react.default.createElement("span", {
352
+ className: "character-viewer__monitor__line__label"
353
+ }, line.label), /*#__PURE__*/_react.default.createElement("span", {
354
+ className: "character-viewer__monitor__line__value"
355
+ }, line.value)))), /*#__PURE__*/_react.default.createElement("div", {
340
356
  className: "character-viewer__monitor__details"
341
357
  }, /*#__PURE__*/_react.default.createElement("span", null, "Font style"), /*#__PURE__*/_react.default.createElement("span", null, /*#__PURE__*/_react.default.createElement(_StyleSelect.default, {
342
358
  collections: families,
@@ -0,0 +1 @@
1
+ export declare function renderCorsErrorModal(origin: string, fontdueUrl: string): void;
@@ -0,0 +1,99 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.renderCorsErrorModal = renderCorsErrorModal;
7
+ var _react = _interopRequireDefault(require("react"));
8
+ var _client = require("react-dom/client");
9
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
10
+ const code = {
11
+ background: '#fef2f2',
12
+ padding: '2px 6px',
13
+ borderRadius: 3,
14
+ fontSize: 13
15
+ };
16
+ function CorsErrorModal(_ref) {
17
+ let {
18
+ origin,
19
+ fontdueUrl
20
+ } = _ref;
21
+ let settingsOrigin = fontdueUrl;
22
+ try {
23
+ settingsOrigin = new URL(fontdueUrl).origin;
24
+ } catch {
25
+ // keep as-is
26
+ }
27
+ return /*#__PURE__*/_react.default.createElement("div", {
28
+ style: {
29
+ position: 'fixed',
30
+ inset: 0,
31
+ zIndex: 99999,
32
+ display: 'flex',
33
+ alignItems: 'center',
34
+ justifyContent: 'center',
35
+ background: 'rgba(0,0,0,0.4)',
36
+ fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
37
+ fontSize: 14,
38
+ lineHeight: 1.6
39
+ }
40
+ }, /*#__PURE__*/_react.default.createElement("div", {
41
+ style: {
42
+ background: 'white',
43
+ color: '#1f2937',
44
+ borderRadius: 12,
45
+ border: '2px solid #fca5a5',
46
+ padding: '28px 32px',
47
+ maxWidth: 520,
48
+ width: '90%',
49
+ boxShadow: '0 8px 30px rgba(0,0,0,0.12)',
50
+ textAlign: 'left'
51
+ }
52
+ }, /*#__PURE__*/_react.default.createElement("strong", {
53
+ style: {
54
+ fontSize: 16,
55
+ color: '#dc2626'
56
+ }
57
+ }, "Cross-origin request blocked"), /*#__PURE__*/_react.default.createElement("p", {
58
+ style: {
59
+ margin: '12px 0 0'
60
+ }
61
+ }, "Your website (", /*#__PURE__*/_react.default.createElement("code", {
62
+ style: code
63
+ }, origin), ") is not allowed to connect to your Fontdue store."), /*#__PURE__*/_react.default.createElement("p", {
64
+ style: {
65
+ margin: '12px 0 0'
66
+ }
67
+ }, "To fix this, go to", ' ', /*#__PURE__*/_react.default.createElement("a", {
68
+ href: `${settingsOrigin}/admin/settings/security`,
69
+ target: "_blank",
70
+ rel: "noreferrer",
71
+ style: {
72
+ color: '#dc2626',
73
+ fontWeight: 500
74
+ }
75
+ }, "Settings \u2192 Security"), ' ', "in your Fontdue dashboard, and add ", /*#__PURE__*/_react.default.createElement("code", {
76
+ style: code
77
+ }, origin), " to the", ' ', /*#__PURE__*/_react.default.createElement("strong", null, "Cross-origin API access"), " field."), /*#__PURE__*/_react.default.createElement("p", {
78
+ style: {
79
+ margin: '16px 0 0',
80
+ color: '#6b7280',
81
+ fontSize: 13
82
+ }
83
+ }, "This page will reload automatically once the origin is added.")));
84
+ }
85
+ function mount(origin, fontdueUrl) {
86
+ const container = document.createElement('div');
87
+ document.body.appendChild(container);
88
+ (0, _client.createRoot)(container).render( /*#__PURE__*/_react.default.createElement(CorsErrorModal, {
89
+ origin: origin,
90
+ fontdueUrl: fontdueUrl
91
+ }));
92
+ }
93
+ function renderCorsErrorModal(origin, fontdueUrl) {
94
+ if (document.body) {
95
+ mount(origin, fontdueUrl);
96
+ } else {
97
+ document.addEventListener('DOMContentLoaded', () => mount(origin, fontdueUrl));
98
+ }
99
+ }
@@ -22,11 +22,12 @@ function OrderVariableSelectionRedux(_ref) {
22
22
  } = _ref;
23
23
  const environment = (0, _reactRelay.useRelayEnvironment)();
24
24
  const [viewer, refetch] = (0, _reactRelay.useRefetchableFragment)((_OrderVariableSelectionRedux_viewer2.default.hash && _OrderVariableSelectionRedux_viewer2.default.hash !== "eaa5e1fdf47cb582dd3c7bdea0a5e6b2" && console.error("The definition of 'OrderVariableSelectionRedux_viewer' appears to have changed. Run `relay-compiler` to update the generated files to receive the expected data."), _OrderVariableSelectionRedux_viewer2.default), viewerKey);
25
+ const refetchVariables = (0, _react.useMemo)(() => ({}), []);
25
26
  (0, _useRefetchOnLicenseChanges.useRefetchOnLicenseChanges)({
26
27
  environment,
27
28
  refetch,
28
29
  query: _OrderVariableSelectionReduxRefetchQuery.default,
29
- variables: {}
30
+ variables: refetchVariables
30
31
  });
31
32
  const dispatch = (0, _reactRedux.useDispatch)();
32
33
  const selections = (0, _reactRedux.useSelector)(state => state.orderVariableSelections);
@@ -37,7 +37,7 @@ function StoreModalFamily(_ref) {
37
37
  onSelect,
38
38
  title
39
39
  } = _ref;
40
- const collection = (0, _reactRelay.useFragment)((_StoreModalFamily_collection2.default.hash && _StoreModalFamily_collection2.default.hash !== "51b251c104458b299f057eaacf85ae52" && console.error("The definition of 'StoreModalFamily_collection' appears to have changed. Run `relay-compiler` to update the generated files to receive the expected data."), _StoreModalFamily_collection2.default), collectionKey);
40
+ const collection = (0, _reactRelay.useFragment)((_StoreModalFamily_collection2.default.hash && _StoreModalFamily_collection2.default.hash !== "9c85d32d917e909af575bdda90949c0b" && console.error("The definition of 'StoreModalFamily_collection' appears to have changed. Run `relay-compiler` to update the generated files to receive the expected data."), _StoreModalFamily_collection2.default), collectionKey);
41
41
  const fontStyles = (0, _react.useMemo)(() => stylesGrouped(collection), [collection]);
42
42
  if ((fontStyles === null || fontStyles === void 0 ? void 0 : fontStyles.length) === 0 && collection.collectionType === 'superfamily' && !collection.sku) return null;
43
43
  return /*#__PURE__*/_react.default.createElement(_StoreModalFamily.default, null, {
@@ -49,7 +49,7 @@ function StoreModalFamily(_ref) {
49
49
  collection: collection,
50
50
  onSelectSku: onSelect
51
51
  }),
52
- bundles: collection === null || collection === void 0 ? void 0 : (_collection$bundles = collection.bundles) === null || _collection$bundles === void 0 ? void 0 : _collection$bundles.map(bundle => /*#__PURE__*/_react.default.createElement(_StoreModalBundleButton.default, {
52
+ bundles: collection === null || collection === void 0 ? void 0 : (_collection$bundles = collection.bundles) === null || _collection$bundles === void 0 ? void 0 : _collection$bundles.filter(bundle => !bundle.hidden).map(bundle => /*#__PURE__*/_react.default.createElement(_StoreModalBundleButton.default, {
53
53
  key: bundle.id,
54
54
  bundle: bundle,
55
55
  onSelectSku: onSelect
@@ -0,0 +1,5 @@
1
+ export interface CorsError {
2
+ origin: string;
3
+ fontdueUrl: string;
4
+ }
5
+ export declare function handlePossibleCorsError(error: unknown, fetchUrl: string): boolean;
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.handlePossibleCorsError = handlePossibleCorsError;
7
+ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
8
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
9
+ let detected = false;
10
+ let navigating = false;
11
+ if (typeof window !== 'undefined') {
12
+ window.addEventListener('beforeunload', () => {
13
+ navigating = true;
14
+ });
15
+ }
16
+ function isCrossOrigin(fetchUrl) {
17
+ try {
18
+ const url = new URL(fetchUrl, window.location.href);
19
+ return url.origin !== window.location.origin;
20
+ } catch {
21
+ return false;
22
+ }
23
+ }
24
+ function startPolling(fetchUrl) {
25
+ const interval = setInterval(async () => {
26
+ try {
27
+ await fetch(fetchUrl, {
28
+ method: 'POST',
29
+ credentials: 'include'
30
+ });
31
+ clearInterval(interval);
32
+ window.location.reload();
33
+ } catch {
34
+ // still blocked, keep polling
35
+ }
36
+ }, 3000);
37
+ }
38
+ function handlePossibleCorsError(error, fetchUrl) {
39
+ if (typeof window === 'undefined') return false;
40
+ if (!(error instanceof TypeError)) return false;
41
+ if (navigating) return false;
42
+ if (!isCrossOrigin(fetchUrl)) return false;
43
+ if (detected) return true;
44
+ detected = true;
45
+ const origin = window.location.origin;
46
+ console.error(`[Fontdue] Cross-origin request to ${fetchUrl} was blocked.\n\n` + `Your website (${origin}) is not listed as an allowed origin ` + `in your Fontdue CORS settings.\n\n` + `To fix this:\n` + `1. Log in to your Fontdue dashboard\n` + `2. Go to Settings \u2192 Security\n` + `3. Add "${origin}" to the "Cross-origin API access" field\n` + `4. Save \u2014 this page will reload automatically`);
47
+ Promise.resolve().then(() => _interopRequireWildcard(require('./components/CorsErrorModal'))).then(_ref => {
48
+ let {
49
+ renderCorsErrorModal
50
+ } = _ref;
51
+ renderCorsErrorModal(origin, fetchUrl);
52
+ });
53
+ startPolling(fetchUrl);
54
+ return true;
55
+ }
package/dist/fontdue.css CHANGED
@@ -868,6 +868,10 @@ div[data-component=TypeTesters] {
868
868
  --section_spacing: 60px;
869
869
  }
870
870
 
871
+ .price {
872
+ font-variant-numeric: tabular-nums;
873
+ }
874
+
871
875
  .character-viewer {
872
876
  --size: calc(var(--monitor-width) * 1 / 2);
873
877
  --half-gap: calc(var(--line-gap) / 2);
@@ -2533,7 +2537,6 @@ body[data-fontdue-store-modal=open] {
2533
2537
  }
2534
2538
  .cart-item__price {
2535
2539
  margin-top: 20px;
2536
- font-variant-numeric: tabular-nums;
2537
2540
  }
2538
2541
  .cart-item:first-child .cart-item__price {
2539
2542
  margin-top: 0;
@@ -2618,6 +2621,7 @@ body[data-fontdue-store-modal=open] {
2618
2621
  text-transform: inherit;
2619
2622
  margin-left: 10px;
2620
2623
  margin-right: -3px;
2624
+ vertical-align: middle;
2621
2625
  }
2622
2626
  .cart__remove-discount-button:active, .cart__remove-discount-button:focus {
2623
2627
  outline: none;
@@ -8,6 +8,7 @@ exports.responseCache = exports.networkFetch = void 0;
8
8
  exports.useCurrentEnvironment = useCurrentEnvironment;
9
9
  var _react = require("react");
10
10
  var _relayRuntime = require("relay-runtime");
11
+ var _corsError = require("../corsError");
11
12
  var _package = require("../../package.json");
12
13
  // @ts-ignore - JSON import
13
14
 
@@ -22,35 +23,48 @@ const CACHE_TTL = 10 * 1000; // 10 seconds, to resolve preloaded results
22
23
  function createNetworkFetch(options) {
23
24
  return async function networkFetch(request, variables) {
24
25
  const url = (FONTDUE_URL && `${FONTDUE_URL}/graphql`) ?? ((options === null || options === void 0 ? void 0 : options.url) ?? '') + '/graphql';
25
- const resp = await fetch(url + `?queryName=${request.name}`, {
26
- method: 'POST',
27
- credentials: 'include',
28
- headers: {
29
- Accept: 'application/json',
30
- 'Content-Type': 'application/json',
31
- 'fontdue-stripe-integration': STRIPE_INTEGRATION ?? ((options === null || options === void 0 ? void 0 : options.stripeIntegration) || 'dynamic'),
32
- 'fontdue-client-version': _package.version
33
- },
34
- body: JSON.stringify({
35
- query: request.text,
36
- variables
37
- }),
38
- // @ts-ignore
39
- next: {
40
- tags: ['graphql', `operation:${request.name}`]
26
+ let resp;
27
+ try {
28
+ resp = await fetch(url + `?queryName=${request.name}`, {
29
+ method: 'POST',
30
+ credentials: 'include',
31
+ headers: {
32
+ Accept: 'application/json',
33
+ 'Content-Type': 'application/json',
34
+ 'fontdue-stripe-integration': STRIPE_INTEGRATION ?? ((options === null || options === void 0 ? void 0 : options.stripeIntegration) || 'dynamic'),
35
+ 'fontdue-client-version': _package.version
36
+ },
37
+ body: JSON.stringify({
38
+ query: request.text,
39
+ variables
40
+ }),
41
+ // @ts-ignore
42
+ next: {
43
+ tags: ['graphql', `operation:${request.name}`]
44
+ }
45
+ });
46
+ } catch (error) {
47
+ if ((0, _corsError.handlePossibleCorsError)(error, url)) {
48
+ return {
49
+ data: undefined,
50
+ errors: [{
51
+ message: 'Cross-origin request blocked'
52
+ }]
53
+ };
41
54
  }
42
- });
55
+ throw error;
56
+ }
43
57
  const json = await resp.json();
44
58
 
45
59
  // GraphQL returns exceptions (for example, a missing required variable) in the "errors"
46
60
  // property of the response. If any exceptions occurred when processing the request,
47
61
  // throw an error to indicate to the developer what went wrong.
48
62
  if (Array.isArray(json.errors)) {
49
- var _json$errors;
63
+ var _json$errors, _error$extensions;
50
64
  const error = (_json$errors = json.errors) === null || _json$errors === void 0 ? void 0 : _json$errors[0];
51
65
  console.error('GraphQL Error:', {
52
66
  message: error.message,
53
- code: error.code,
67
+ code: (_error$extensions = error.extensions) === null || _error$extensions === void 0 ? void 0 : _error$extensions.code,
54
68
  path: error.path
55
69
  });
56
70
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fontdue-js",
3
- "version": "2.18.4",
3
+ "version": "2.19.0",
4
4
  "scripts": {
5
5
  "build": "npm run relay && run-p build-js build-css build-ts",
6
6
  "build-js": "babel src --out-dir dist --extensions .ts,.tsx,.js,.jsx",