fontdue-js 0.1.0-alpha11 → 0.1.0-alpha12

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.
@@ -28,8 +28,8 @@ fragment TestFontsForm_viewer on Viewer {
28
28
  id
29
29
  }
30
30
  settings {
31
- eulaAgreementLabel
32
- newsletterOptInLabel
31
+ eulaAgreementLabel(format: HTML)
32
+ newsletterOptInLabel(format: HTML)
33
33
  }
34
34
  testFonts {
35
35
  archiveUrl
@@ -43,7 +43,12 @@ const node = function () {
43
43
  "kind": "ScalarField",
44
44
  "name": "id",
45
45
  "storageKey": null
46
- };
46
+ },
47
+ v1 = [{
48
+ "kind": "Literal",
49
+ "name": "format",
50
+ "value": "HTML"
51
+ }];
47
52
  return {
48
53
  "fragment": {
49
54
  "argumentDefinitions": [],
@@ -122,16 +127,20 @@ const node = function () {
122
127
  "plural": false,
123
128
  "selections": [{
124
129
  "alias": null,
125
- "args": null,
130
+ "args": v1
131
+ /*: any*/
132
+ ,
126
133
  "kind": "ScalarField",
127
134
  "name": "eulaAgreementLabel",
128
- "storageKey": null
135
+ "storageKey": "eulaAgreementLabel(format:\"HTML\")"
129
136
  }, {
130
137
  "alias": null,
131
- "args": null,
138
+ "args": v1
139
+ /*: any*/
140
+ ,
132
141
  "kind": "ScalarField",
133
142
  "name": "newsletterOptInLabel",
134
- "storageKey": null
143
+ "storageKey": "newsletterOptInLabel(format:\"HTML\")"
135
144
  }],
136
145
  "storageKey": null
137
146
  }, {
@@ -156,12 +165,12 @@ const node = function () {
156
165
  }]
157
166
  },
158
167
  "params": {
159
- "cacheID": "878f0047db453a740384a7e7f7d67e4a",
168
+ "cacheID": "598b43f60c1a9c3b5284c2b0532eec1d",
160
169
  "id": null,
161
170
  "metadata": {},
162
171
  "name": "TestFontsForm_Query",
163
172
  "operationKind": "query",
164
- "text": "query TestFontsForm_Query {\n viewer {\n ...TestFontsForm_viewer\n id\n }\n}\n\nfragment TestFontsForm_viewer on Viewer {\n currentOrder {\n customer {\n name\n email\n id\n }\n id\n }\n settings {\n eulaAgreementLabel\n newsletterOptInLabel\n }\n testFonts {\n archiveUrl\n }\n}\n"
173
+ "text": "query TestFontsForm_Query {\n viewer {\n ...TestFontsForm_viewer\n id\n }\n}\n\nfragment TestFontsForm_viewer on Viewer {\n currentOrder {\n customer {\n name\n email\n id\n }\n id\n }\n settings {\n eulaAgreementLabel(format: HTML)\n newsletterOptInLabel(format: HTML)\n }\n testFonts {\n archiveUrl\n }\n}\n"
165
174
  }
166
175
  };
167
176
  }();
@@ -9,81 +9,93 @@ exports.default = void 0;
9
9
 
10
10
  /* eslint-disable */
11
11
  // @ts-nocheck
12
- const node = {
13
- "argumentDefinitions": [],
14
- "kind": "Fragment",
15
- "metadata": null,
16
- "name": "TestFontsForm_viewer",
17
- "selections": [{
18
- "alias": null,
19
- "args": null,
20
- "concreteType": "Order",
21
- "kind": "LinkedField",
22
- "name": "currentOrder",
23
- "plural": false,
12
+ const node = function () {
13
+ var v0 = [{
14
+ "kind": "Literal",
15
+ "name": "format",
16
+ "value": "HTML"
17
+ }];
18
+ return {
19
+ "argumentDefinitions": [],
20
+ "kind": "Fragment",
21
+ "metadata": null,
22
+ "name": "TestFontsForm_viewer",
24
23
  "selections": [{
25
24
  "alias": null,
26
25
  "args": null,
27
- "concreteType": "Customer",
26
+ "concreteType": "Order",
28
27
  "kind": "LinkedField",
29
- "name": "customer",
28
+ "name": "currentOrder",
30
29
  "plural": false,
31
30
  "selections": [{
32
31
  "alias": null,
33
32
  "args": null,
34
- "kind": "ScalarField",
35
- "name": "name",
36
- "storageKey": null
37
- }, {
38
- "alias": null,
39
- "args": null,
40
- "kind": "ScalarField",
41
- "name": "email",
33
+ "concreteType": "Customer",
34
+ "kind": "LinkedField",
35
+ "name": "customer",
36
+ "plural": false,
37
+ "selections": [{
38
+ "alias": null,
39
+ "args": null,
40
+ "kind": "ScalarField",
41
+ "name": "name",
42
+ "storageKey": null
43
+ }, {
44
+ "alias": null,
45
+ "args": null,
46
+ "kind": "ScalarField",
47
+ "name": "email",
48
+ "storageKey": null
49
+ }],
42
50
  "storageKey": null
43
51
  }],
44
52
  "storageKey": null
45
- }],
46
- "storageKey": null
47
- }, {
48
- "alias": null,
49
- "args": null,
50
- "concreteType": "Settings",
51
- "kind": "LinkedField",
52
- "name": "settings",
53
- "plural": false,
54
- "selections": [{
55
- "alias": null,
56
- "args": null,
57
- "kind": "ScalarField",
58
- "name": "eulaAgreementLabel",
59
- "storageKey": null
60
53
  }, {
61
54
  "alias": null,
62
55
  "args": null,
63
- "kind": "ScalarField",
64
- "name": "newsletterOptInLabel",
56
+ "concreteType": "Settings",
57
+ "kind": "LinkedField",
58
+ "name": "settings",
59
+ "plural": false,
60
+ "selections": [{
61
+ "alias": null,
62
+ "args": v0
63
+ /*: any*/
64
+ ,
65
+ "kind": "ScalarField",
66
+ "name": "eulaAgreementLabel",
67
+ "storageKey": "eulaAgreementLabel(format:\"HTML\")"
68
+ }, {
69
+ "alias": null,
70
+ "args": v0
71
+ /*: any*/
72
+ ,
73
+ "kind": "ScalarField",
74
+ "name": "newsletterOptInLabel",
75
+ "storageKey": "newsletterOptInLabel(format:\"HTML\")"
76
+ }],
65
77
  "storageKey": null
66
- }],
67
- "storageKey": null
68
- }, {
69
- "alias": null,
70
- "args": null,
71
- "concreteType": "TestFonts",
72
- "kind": "LinkedField",
73
- "name": "testFonts",
74
- "plural": false,
75
- "selections": [{
78
+ }, {
76
79
  "alias": null,
77
80
  "args": null,
78
- "kind": "ScalarField",
79
- "name": "archiveUrl",
81
+ "concreteType": "TestFonts",
82
+ "kind": "LinkedField",
83
+ "name": "testFonts",
84
+ "plural": false,
85
+ "selections": [{
86
+ "alias": null,
87
+ "args": null,
88
+ "kind": "ScalarField",
89
+ "name": "archiveUrl",
90
+ "storageKey": null
91
+ }],
80
92
  "storageKey": null
81
93
  }],
82
- "storageKey": null
83
- }],
84
- "type": "Viewer",
85
- "abstractKey": null
86
- };
87
- node.hash = '843da38f2f0593804778f3894731351d';
94
+ "type": "Viewer",
95
+ "abstractKey": null
96
+ };
97
+ }();
98
+
99
+ node.hash = '4b3632aa1b6b2a5525ec749ab67f1cde';
88
100
  var _default = node;
89
101
  exports.default = _default;
@@ -1,10 +1,10 @@
1
1
  import React from 'react';
2
2
  import { Config } from '../ConfigContext';
3
3
  import { Components } from '../ComponentsContext';
4
- interface FontdueProviderProps {
4
+ export interface FontdueProvider_props {
5
5
  url: string;
6
6
  config?: Config;
7
7
  components?: Components;
8
8
  }
9
- declare const FontdueProvider: React.FC<FontdueProviderProps>;
9
+ declare const FontdueProvider: React.FC<FontdueProvider_props>;
10
10
  export default FontdueProvider;
@@ -0,0 +1,4 @@
1
+ /// <reference types="react" />
2
+ import { FontdueProvider_props } from '../FontdueProvider';
3
+ declare const Root: (props: FontdueProvider_props) => JSX.Element;
4
+ export default Root;
@@ -5,12 +5,14 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.default = void 0;
7
7
 
8
- var _react = _interopRequireDefault(require("react"));
8
+ var _react = _interopRequireWildcard(require("react"));
9
9
 
10
10
  var _reactDom = _interopRequireDefault(require("react-dom"));
11
11
 
12
12
  var _reactLoadable = _interopRequireDefault(require("react-loadable"));
13
13
 
14
+ var _uuid = require("uuid");
15
+
14
16
  var _utils = require("../../utils");
15
17
 
16
18
  var _FontdueProvider = _interopRequireDefault(require("../FontdueProvider"));
@@ -34,32 +36,30 @@ const loadable = loader => (0, _reactLoadable.default)({
34
36
  }
35
37
  });
36
38
 
37
- const componentMap = {
38
- Precart: loadable(() => Promise.resolve().then(() => _interopRequireWildcard(require('../Precart')))),
39
- BuyingOptions: loadable(() => Promise.resolve().then(() => _interopRequireWildcard(require('../BuyingOptions')))),
40
- AddToCartBanner: loadable(() => Promise.resolve().then(() => _interopRequireWildcard(require('../AddToCartBanner')))),
41
- CookieNotification: loadable(() => Promise.resolve().then(() => _interopRequireWildcard(require('../CookieNotification')))),
42
- Cart: loadable(() => Promise.resolve().then(() => _interopRequireWildcard(require('../Cart')))),
43
- CartButton: loadable(() => Promise.resolve().then(() => _interopRequireWildcard(require('../CartButton')))),
44
- TypeTesters: loadable(() => Promise.resolve().then(() => _interopRequireWildcard(require('../TypeTesters')))),
45
- TypeTester: loadable(() => Promise.resolve().then(() => _interopRequireWildcard(require('../TypeTester/TypeTesterStandalone')))),
46
- SpecimenLink: loadable(() => Promise.resolve().then(() => _interopRequireWildcard(require('../SpecimenLink')))),
47
- StickyNav: loadable(() => Promise.resolve().then(() => _interopRequireWildcard(require('../StickyNav')))),
48
- StoreModal: loadable(() => Promise.resolve().then(() => _interopRequireWildcard(require('../StoreModal')))),
49
- FontFamilies: loadable(() => Promise.resolve().then(() => _interopRequireWildcard(require('../FontFamilies')))),
50
- CollectionAa: loadable(() => Promise.resolve().then(() => _interopRequireWildcard(require('../CollectionAa')))),
51
- TestFontsForm: loadable(() => Promise.resolve().then(() => _interopRequireWildcard(require('../TestFontsForm')))),
52
- NewsletterSignup: loadable(() => Promise.resolve().then(() => _interopRequireWildcard(require('../NewsletterSignup')))),
53
- BuyButton: loadable(() => Promise.resolve().then(() => _interopRequireWildcard(require('../BuyButton'))))
54
- };
55
39
  const customElementMap = {
56
- 'fontdue-buy-button': componentMap.BuyButton,
57
- 'fontdue-cart-button': componentMap.CartButton,
58
- 'fontdue-newsletter-signup': componentMap.NewsletterSignup,
59
- 'fontdue-store-modal': componentMap.StoreModal,
60
- 'fontdue-test-fonts-form': componentMap.TestFontsForm,
61
- 'fontdue-type-testers': componentMap.TypeTesters,
62
- 'fontdue-type-tester': componentMap.TypeTester
40
+ // @ts-ignore
41
+ 'fontdue-add-to-cart-banner': loadable(() => Promise.resolve().then(() => _interopRequireWildcard(require('../AddToCartBanner')))),
42
+ // @ts-ignore
43
+ 'fontdue-buying-options': loadable(() => Promise.resolve().then(() => _interopRequireWildcard(require('../BuyingOptions')))),
44
+ 'fontdue-buy-button': loadable(() => Promise.resolve().then(() => _interopRequireWildcard(require('../BuyButton')))),
45
+ 'fontdue-cart': loadable(() => Promise.resolve().then(() => _interopRequireWildcard(require('../Cart')))),
46
+ 'fontdue-cart-button': loadable(() => Promise.resolve().then(() => _interopRequireWildcard(require('../CartButton')))),
47
+ // @ts-ignore
48
+ 'fontdue-collection-aa': loadable(() => Promise.resolve().then(() => _interopRequireWildcard(require('../CollectionAa')))),
49
+ // @ts-ignore
50
+ 'fontdue-cookie-notification': loadable(() => Promise.resolve().then(() => _interopRequireWildcard(require('../CookieNotification')))),
51
+ 'fontdue-font-families': loadable(() => Promise.resolve().then(() => _interopRequireWildcard(require('../FontFamilies')))),
52
+ 'fontdue-newsletter-signup': loadable(() => Promise.resolve().then(() => _interopRequireWildcard(require('../NewsletterSignup')))),
53
+ // @ts-ignore
54
+ 'fontdue-precart': loadable(() => Promise.resolve().then(() => _interopRequireWildcard(require('../Precart')))),
55
+ // @ts-ignore
56
+ 'fontdue-specimen-link': loadable(() => Promise.resolve().then(() => _interopRequireWildcard(require('../SpecimenLink')))),
57
+ // @ts-ignore
58
+ 'fontdue-sticky-nav': loadable(() => Promise.resolve().then(() => _interopRequireWildcard(require('../StickyNav')))),
59
+ 'fontdue-store-modal': loadable(() => Promise.resolve().then(() => _interopRequireWildcard(require('../StoreModal')))),
60
+ 'fontdue-test-fonts-form': loadable(() => Promise.resolve().then(() => _interopRequireWildcard(require('../TestFontsForm')))),
61
+ 'fontdue-type-tester': loadable(() => Promise.resolve().then(() => _interopRequireWildcard(require('../TypeTester/TypeTesterStandalone')))),
62
+ 'fontdue-type-testers': loadable(() => Promise.resolve().then(() => _interopRequireWildcard(require('../TypeTesters'))))
63
63
  };
64
64
  Object.keys(customElementMap).forEach(elementName => {
65
65
  // this might be more sophisticated in the future with a shadow DOM, etc,
@@ -69,44 +69,87 @@ Object.keys(customElementMap).forEach(elementName => {
69
69
  customElements.define(elementName, FontdueElement);
70
70
  });
71
71
 
72
- const renderComponent = (element, i) => {
73
- const {
74
- component,
75
- ...data
76
- } = element.dataset;
77
- const Component = componentMap[component];
78
-
79
- if (typeof Component === 'undefined') {
80
- // eslint-disable-next-line no-console
81
- console.warn("Tried to mount ".concat(component, " but it wasn't imported into Root"));
82
- return null;
83
- }
84
-
85
- return /*#__PURE__*/_reactDom.default.createPortal( /*#__PURE__*/_react.default.createElement(Component, _extends({}, data, {
86
- key: i
87
- })), element);
88
- };
89
-
90
- const renderCustomElement = (element, i) => {
72
+ const renderCustomElement = (element, key) => {
91
73
  const Component = customElementMap[element.nodeName.toLowerCase()];
92
74
  const attributes = element.getAttributeNames();
93
75
  const props = attributes.reduce((acc, attribute) => {
94
- acc[(0, _utils.kebabToCamel)(attribute)] = element.getAttribute(attribute);
76
+ var _element$getAttribute;
77
+
78
+ acc[(0, _utils.kebabToCamel)(attribute)] = (_element$getAttribute = element.getAttribute(attribute)) !== null && _element$getAttribute !== void 0 ? _element$getAttribute : '';
95
79
  return acc;
96
80
  }, {});
97
81
  return /*#__PURE__*/_reactDom.default.createPortal( /*#__PURE__*/_react.default.createElement(Component, _extends({}, props, {
98
- key: i
82
+ key: key
99
83
  })), element);
100
84
  };
101
85
 
86
+ const customElementTags = Object.keys(customElementMap);
87
+
88
+ const allFontdueElements = element => customElementTags.flatMap(elementName => Array.from(element.querySelectorAll(elementName)));
89
+
90
+ const getInitialElements = () => {
91
+ const map = new Map();
92
+ allFontdueElements(document.body).forEach(element => map.set(element, (0, _uuid.v4)()));
93
+ return map;
94
+ };
95
+
102
96
  const Root = props => {
103
- const componentElements = Array.from(document.querySelectorAll('[data-component]'));
104
- const customElements = Object.keys(customElementMap).flatMap(elementName => Array.from(document.querySelectorAll(elementName)));
97
+ // use a Map here instead of an array in case we register the same element
98
+ // more than once (otherwise we run into issues rendering the component
99
+ // twice into the same element). this also gives us a way to set unique keys.
100
+ const [elements, setElements] = (0, _react.useState)(getInitialElements());
101
+ (0, _react.useEffect)(() => {
102
+ // watch for any new or removed fontdue elements
103
+ const mutationObserver = new MutationObserver(mutations => {
104
+ mutations.forEach(mutation => {
105
+ mutation.addedNodes.forEach(node => {
106
+ if (!(node instanceof HTMLElement)) return;
107
+ let newElements = [];
108
+
109
+ if (customElementTags.includes(node.nodeName.toLowerCase())) {
110
+ newElements.push(node);
111
+ }
112
+
113
+ newElements = newElements.concat(allFontdueElements(node));
114
+
115
+ if (newElements.length > 0) {
116
+ setElements(elements => {
117
+ const newMap = new Map(elements);
118
+ newElements.forEach(el => newMap.set(el, (0, _uuid.v4)()));
119
+ return newMap;
120
+ });
121
+ }
122
+ });
123
+ mutation.removedNodes.forEach(node => {
124
+ if (!(node instanceof HTMLElement)) return;
125
+ let removedElements = [];
126
+
127
+ if (customElementTags.includes(node.nodeName.toLowerCase())) {
128
+ removedElements.push(node);
129
+ }
130
+
131
+ removedElements = removedElements.concat(allFontdueElements(node));
132
+
133
+ if (removedElements.length > 0) {
134
+ setElements(elements => {
135
+ const newMap = new Map(elements);
136
+ removedElements.forEach(el => newMap.delete(el));
137
+ return newMap;
138
+ });
139
+ }
140
+ });
141
+ });
142
+ });
143
+ mutationObserver.observe(document.body, {
144
+ subtree: true,
145
+ childList: true
146
+ });
147
+ }, []);
105
148
  return /*#__PURE__*/_react.default.createElement(_FontdueProvider.default, {
106
149
  url: props.url,
107
150
  config: props.config,
108
151
  components: props.components
109
- }, /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, componentElements.map(renderComponent)), /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, customElements.map(renderCustomElement)));
152
+ }, /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, Array.from(elements).map(([el, key]) => renderCustomElement(el, key))));
110
153
  };
111
154
 
112
155
  var _default = Root;
@@ -30,7 +30,6 @@ const createRouter = (store, environment) => {
30
30
  currentRoute = store.getState().storeModalRoute;
31
31
 
32
32
  if (currentRoute !== previousRoute) {
33
- console.log(currentRoute);
34
33
  currentEntry = prepareRoute(currentRoute, environment);
35
34
  subscribers.forEach(cb => cb(currentEntry));
36
35
  }
@@ -124,9 +124,9 @@ const TypeTesterComponent = ({
124
124
  config: config
125
125
  }), ((_config$priceText = config.priceText) !== null && _config$priceText !== void 0 ? _config$priceText : false) && fontStyle.sku && /*#__PURE__*/_react.default.createElement("div", {
126
126
  className: "type-tester__toolbar__price-text"
127
- }, "From ", /*#__PURE__*/_react.default.createElement(_SKUPrice.default, {
127
+ }, /*#__PURE__*/_react.default.createElement(_SKUPrice.default, {
128
128
  sku: fontStyle.sku
129
- }), " excl. VAT"), /*#__PURE__*/_react.default.createElement("div", {
129
+ })), /*#__PURE__*/_react.default.createElement("div", {
130
130
  className: "type-tester__toolbar__tools"
131
131
  }, /*#__PURE__*/_react.default.createElement("div", {
132
132
  className: "type-tester__slider"