@bikematrix/web-components 1.0.18 → 1.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 +54 -3
- package/dist/bm_core.es.js +27 -25
- package/dist/bm_core.js +3 -3
- package/dist/bm_core.umd.js +3 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
# Bike Matrix Web Components
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Our Mission is to transform the bicycle industry by offering a comprehensive compatibility solution to all retailers, service providers, manufacturers, and riders, by seamlessly connecting replacement parts to a specific bike.
|
|
4
|
+
|
|
5
|
+
Using the Bike Matrix Web Components allows any web application to provide its users the accurate selection of a bike from our database of over 50,000 Bikes by Brand, Model, Spec, Year and Size. The web application can then run a series of complex compatibility algorithms over the nominated EAN, UPC or Manufacturer Part Number, returning a Compatibility Result with messages for display to your users for the selected bike and component.
|
|
6
|
+
|
|
7
|
+

|
|
4
8
|
|
|
5
9
|
## Table of Contents
|
|
6
10
|
|
|
11
|
+
- [Introduction](#introduction)
|
|
7
12
|
- [Installation](#installation)
|
|
8
13
|
- [Getting Started](#getting-started)
|
|
9
14
|
- [Configuration](#configuration)
|
|
@@ -17,6 +22,48 @@ A web component library for integrating bike matrix compatibility checking into
|
|
|
17
22
|
- [Framework Integration](#framework-integration)
|
|
18
23
|
- [Common Scenarios](#common-scenarios)
|
|
19
24
|
|
|
25
|
+
## Introduction
|
|
26
|
+
|
|
27
|
+
Bike Matrix is a compatibility solution that answers the question, which parts fit this bike?
|
|
28
|
+
We provide the ability for a user to select a bike and see which parts, from your available products, are suitable replacement or upgrades by processing mechanic-led, component-level compatibility assessment on the products being viewed, searched or filtered.
|
|
29
|
+
|
|
30
|
+
The Web Components are pre-built Javascript components that can quickly be placed on your website and can provide you with the list of bikes that we have in our database and, along with images, can allow a user to easily select their bike. We have over 50,000 Bikes by Brand, Make, Model, Spec, Year and Size and are currently working to enrich the data of the remaining 100,000+ bikes in our dataset.
|
|
31
|
+
|
|
32
|
+
We have built up a comprehensive database of components such as Brake Pads, Tyres, Tubes, Brake Rotors, Wheels, Chains, Cassettes, Headsets and many more.
|
|
33
|
+
|
|
34
|
+
As part of the Onboarding process, it is important to talk to us to check that the products on your website that you would like to show compatibility for, are in our database. If the product does not exist in our database just provide us with the information we might need to get the product set up.
|
|
35
|
+
|
|
36
|
+
We use internationally recognised EAN or UPC barcodes, or the Original Manufacturer’s Part Number to identify products being assessed for compatibility. It is imperative that one of these three product identifiers is used. We use this product SKU to determine the Product Category, and therefore the compatibility logic to apply.
|
|
37
|
+
|
|
38
|
+

|
|
39
|
+
|
|
40
|
+
To check if a product is compatible with a specific Bike we first need to guide the user towards finding the exact bike, via our Bike Selector using the following taxonomy: Brand, Model Family, Model Spec, Bike Spec, Year and Size.
|
|
41
|
+
|
|
42
|
+
* Brand is the Bike Brand that makes the Bike.
|
|
43
|
+
* Model Family refers to the high-level name of the Model within the Brand’s portfolio, such as Domane (Trek), Trance (Giant) or Scultura (Merida).
|
|
44
|
+
* Model Spec (sometimes referred to as Frame Spec) is the name for the different frame specifications within a Model Family. It could be that there is only AL(alloy), or perhaps there is Alloy and Carbon or it could be AL, CF, CF SL and CF SLX (eg Canyon).
|
|
45
|
+
* Bike Spec is the ‘spec level’ of each specific Models and can take many forms and include groupset names. It usually contains a number such as 3, 2, 1, and 0 or 200, 400, 500 or it can have Comp, Expert, Pro labels depending on the Brand and Model Family.
|
|
46
|
+
* Year is an obvious one, but the selection of year can change the list of Bike Spec or Model Spec that were available for a given Model Family.
|
|
47
|
+
* Size will depend on the bike brand model and year and can take several forms, S, M, L in some cases, 15”, 16”, 17” in others. Sometimes it’s Short and Long, or S1, S2, S3, S4 (eg Specialized) and for kids bikes we tend to refer to the wheelsize.
|
|
48
|
+
|
|
49
|
+

|
|
50
|
+
|
|
51
|
+
We’ve put considerable effort into designing a Bike Selector that we think guides the user to the correct bike in an easy to understand manner. Unfortunately, some bikes are just confusing, and some customers don’t immediately know which bike they have.
|
|
52
|
+
|
|
53
|
+

|
|
54
|
+
|
|
55
|
+
The other consideration that is very important to us is our Brand Representation. A condition of signing a licence to use Bike Matrix APIs, is the requirement to incorporate our Compatibility Indicators and the “Powered by Bike Matrix” link.
|
|
56
|
+
|
|
57
|
+
The Compatibility Indicators are the graphic representations of Green (Compatible), Amber (Compatible with Conditions) and Red (Not Compatible) on both the Collection or Product Landing Page (PLP), and also on the Product Details Page (PDP). Again, these are all built into the Bike Matrix Web Components.
|
|
58
|
+
|
|
59
|
+
By standardising the look and feel of the compatibility results across all websites, trust is built and confidence is increased, which results in increased conversions. This is also why we recommend locating the Compatibility Indicators close to the Buy Now or Add to Cart buttons, as it will form an important part of the buying journey.
|
|
60
|
+
|
|
61
|
+

|
|
62
|
+
|
|
63
|
+
## Obtaining API Credentials
|
|
64
|
+
|
|
65
|
+
The Web Components require access to the Bike Matrix API. To request access to the Bike Matrix API send us an email at adamb@bikematrix.io and we will create your subscription and provide you with access to our staging APIs allowing you to explore and test functionality. When you’re ready, we can activate your licence and provide access to the entire bike database through the Production API. Depending on your deployment scenario we will provide an API Key or we will add your environments information to our whitelist.
|
|
66
|
+
|
|
20
67
|
## Installation
|
|
21
68
|
|
|
22
69
|
You can install Bike Matrix Web Components using either npm or by including it directly via CDN.
|
|
@@ -40,10 +87,12 @@ Alternatively, include the script directly in your HTML:
|
|
|
40
87
|
```html
|
|
41
88
|
<script
|
|
42
89
|
type="text/javascript"
|
|
43
|
-
src="https://cdn.jsdelivr.net/npm/@bikematrix/web-components/dist/bm_core.js"
|
|
90
|
+
src="https://cdn.jsdelivr.net/npm/@bikematrix/web-components@1.1/dist/bm_core.js"
|
|
44
91
|
></script>
|
|
45
92
|
```
|
|
46
93
|
|
|
94
|
+
Note: Replace version `1.1` in the above URL with the latest version number, or the specific version you want to use.
|
|
95
|
+
|
|
47
96
|
## Getting Started
|
|
48
97
|
|
|
49
98
|
Follow these steps to quickly integrate BikeMatrix into your website:
|
|
@@ -71,10 +120,12 @@ Include the script directly in your HTML:
|
|
|
71
120
|
```html
|
|
72
121
|
<script
|
|
73
122
|
type="text/javascript"
|
|
74
|
-
src="https://cdn.jsdelivr.net/npm/@bikematrix/web-components/dist/bm_core.js"
|
|
123
|
+
src="https://cdn.jsdelivr.net/npm/@bikematrix/web-components@1.1/dist/bm_core.js"
|
|
75
124
|
></script>
|
|
76
125
|
```
|
|
77
126
|
|
|
127
|
+
Note: Replace version `1.1` in the above URL with the latest version number, or the specific version you want to use.
|
|
128
|
+
|
|
78
129
|
### 2. Configure BikeMatrix
|
|
79
130
|
|
|
80
131
|
Add the core configuration block to your HTML:
|
package/dist/bm_core.es.js
CHANGED
|
@@ -1236,9 +1236,9 @@ function Ga(t) {
|
|
|
1236
1236
|
return de(t);
|
|
1237
1237
|
}, []);
|
|
1238
1238
|
}
|
|
1239
|
-
const Gt = de(!1), M = de(null),
|
|
1239
|
+
const Gt = de(!1), M = de(null), Se = de([]), re = de(!1), Ee = de([]), oe = de(!1), Ka = () => {
|
|
1240
1240
|
Ma(() => {
|
|
1241
|
-
M.value = null,
|
|
1241
|
+
M.value = null, Se.value = [], re.value = !1, Ee.value = [], oe.value = !1;
|
|
1242
1242
|
});
|
|
1243
1243
|
}, zo = "bm_currentBike", Ja = "v2", Ya = "https://cdn.bikematrix.io", Pr = {
|
|
1244
1244
|
// Shopify specific
|
|
@@ -3746,7 +3746,10 @@ class St {
|
|
|
3746
3746
|
body: JSON.stringify(r),
|
|
3747
3747
|
method: "POST",
|
|
3748
3748
|
headers: {
|
|
3749
|
-
"Content-Type": "application/json"
|
|
3749
|
+
"Content-Type": "application/json",
|
|
3750
|
+
...this._apiKey && {
|
|
3751
|
+
"bm-subscription-key": this._apiKey
|
|
3752
|
+
}
|
|
3750
3753
|
},
|
|
3751
3754
|
...a
|
|
3752
3755
|
});
|
|
@@ -3932,7 +3935,7 @@ const Io = class Me {
|
|
|
3932
3935
|
this.currentBike === null ? (e = window.bm_selectBikeButton) == null || e.classList.remove("show-selected") : (r = window.bm_selectBikeButton) == null || r.classList.add("show-selected");
|
|
3933
3936
|
}
|
|
3934
3937
|
ChangeBike() {
|
|
3935
|
-
this.config.logLevel === "verbose" && console.log("ChangeBike() Method Called"), !(re.value === !0 || oe.value === !0) && (re.value = !0, oe.value = !0,
|
|
3938
|
+
this.config.logLevel === "verbose" && console.log("ChangeBike() Method Called"), !(re.value === !0 || oe.value === !0) && (re.value = !0, oe.value = !0, Se.value = [], Ee.value = [], console.log("ChangeBike updateBikeSignal..."), this.updateBikeSignal().then(() => {
|
|
3936
3939
|
this.config.logLevel === "verbose" && console.log("Bike Signal Updated: ", JSON.stringify(M.value, null, 2)), this.ResetSelectedBikeIndicator(), this.RefreshCompatibleSkus().then(() => {
|
|
3937
3940
|
document.dispatchEvent(new Event("RefreshCompatibility", {
|
|
3938
3941
|
bubbles: !0,
|
|
@@ -3977,7 +3980,7 @@ const Io = class Me {
|
|
|
3977
3980
|
var a, i;
|
|
3978
3981
|
var r = JSON.parse(sessionStorage.getItem(e));
|
|
3979
3982
|
if (r)
|
|
3980
|
-
this.config.logLevel === "verbose" && console.log("Refresh Collection SKUs from Session: ", JSON.stringify(r), null, 2),
|
|
3983
|
+
this.config.logLevel === "verbose" && console.log("Refresh Collection SKUs from Session: ", JSON.stringify(r), null, 2), Se.value = r;
|
|
3981
3984
|
else {
|
|
3982
3985
|
const n = Object.values(this.config.products || {}).map((p) => p.skus).flat();
|
|
3983
3986
|
this.config.logLevel === "verbose" && console.log("Refresh Collection SKUs from API. SKUs: ", JSON.stringify(n), null, 2);
|
|
@@ -3994,7 +3997,7 @@ const Io = class Me {
|
|
|
3994
3997
|
console.log("function RefreshCompatibleSkus() operation aborted");
|
|
3995
3998
|
return;
|
|
3996
3999
|
}
|
|
3997
|
-
sessionStorage.setItem(e, JSON.stringify(p)),
|
|
4000
|
+
sessionStorage.setItem(e, JSON.stringify(p)), Se.value = p;
|
|
3998
4001
|
} catch (p) {
|
|
3999
4002
|
p.name === "AbortError" ? console.log("function RefreshCompatibleSkus() fetch aborted") : console.error("function RefreshCompatibleSkus() fetch error", p);
|
|
4000
4003
|
} finally {
|
|
@@ -5332,7 +5335,7 @@ function Ko({
|
|
|
5332
5335
|
})]
|
|
5333
5336
|
}) : d(q, {});
|
|
5334
5337
|
}
|
|
5335
|
-
const
|
|
5338
|
+
const Be = {
|
|
5336
5339
|
unavailable: {
|
|
5337
5340
|
heading: ""
|
|
5338
5341
|
},
|
|
@@ -5354,7 +5357,7 @@ const Yi = async (t, e, r) => {
|
|
|
5354
5357
|
if (!r || !Ee.value) {
|
|
5355
5358
|
ie = {
|
|
5356
5359
|
type: "unavailable",
|
|
5357
|
-
...
|
|
5360
|
+
...Be.unavailable
|
|
5358
5361
|
};
|
|
5359
5362
|
return;
|
|
5360
5363
|
}
|
|
@@ -5367,16 +5370,16 @@ const Yi = async (t, e, r) => {
|
|
|
5367
5370
|
const a = o.every((s) => (s == null ? void 0 : s.compatible) === !1), i = o.some((s) => (s == null ? void 0 : s.compatible) === !0 && s.warning === !0), n = o.some((s) => (s == null ? void 0 : s.compatible) === !0);
|
|
5368
5371
|
o.some((s) => (s == null ? void 0 : s.compatible) === null), i ? ie = {
|
|
5369
5372
|
type: "warning",
|
|
5370
|
-
...
|
|
5373
|
+
...Be.warning
|
|
5371
5374
|
} : n ? ie = {
|
|
5372
5375
|
type: "compatible",
|
|
5373
|
-
...
|
|
5376
|
+
...Be.compatible
|
|
5374
5377
|
} : a ? ie = {
|
|
5375
5378
|
type: "incompatible",
|
|
5376
|
-
...
|
|
5379
|
+
...Be.incompatible
|
|
5377
5380
|
} : ie = {
|
|
5378
5381
|
type: "unavailable",
|
|
5379
|
-
...
|
|
5382
|
+
...Be.unavailable
|
|
5380
5383
|
};
|
|
5381
5384
|
}, Wi = function(t, e, r, o, a, i, n) {
|
|
5382
5385
|
var u;
|
|
@@ -5400,7 +5403,7 @@ function Zi({
|
|
|
5400
5403
|
const a = window.BikeMatrix, i = a.getConfig(), [n, s] = Q(!1), u = !!a.getActiveSubscription();
|
|
5401
5404
|
ie = {
|
|
5402
5405
|
type: "unavailable",
|
|
5403
|
-
...
|
|
5406
|
+
...Be.unavailable
|
|
5404
5407
|
};
|
|
5405
5408
|
const {
|
|
5406
5409
|
currentCollectionHandle: l,
|
|
@@ -5659,15 +5662,14 @@ function nn({
|
|
|
5659
5662
|
i(!1);
|
|
5660
5663
|
return;
|
|
5661
5664
|
}
|
|
5662
|
-
|
|
5663
|
-
const B = rn(De.value).map(x);
|
|
5665
|
+
const B = rn(Se.value).map(x);
|
|
5664
5666
|
c(B);
|
|
5665
5667
|
const z = on(y, B);
|
|
5666
5668
|
l(z), i(!0);
|
|
5667
5669
|
}, [
|
|
5668
5670
|
_,
|
|
5669
5671
|
M.value,
|
|
5670
|
-
|
|
5672
|
+
Se.value,
|
|
5671
5673
|
re.value,
|
|
5672
5674
|
// compatibleProducts,
|
|
5673
5675
|
y
|
|
@@ -5997,7 +5999,7 @@ const Ue = () => {
|
|
|
5997
5999
|
for (const o in e)
|
|
5998
6000
|
o !== "__proto__" && o !== "constructor" && (o in t ? typeof t[o] == "string" || t[o] instanceof String || typeof e[o] == "string" || e[o] instanceof String ? r && (t[o] = e[o]) : Yo(t[o], e[o], r) : t[o] = e[o]);
|
|
5999
6001
|
return t;
|
|
6000
|
-
},
|
|
6002
|
+
}, De = (t) => t.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
|
|
6001
6003
|
var hn = {
|
|
6002
6004
|
"&": "&",
|
|
6003
6005
|
"<": "<",
|
|
@@ -6695,7 +6697,7 @@ class Bn {
|
|
|
6695
6697
|
maxReplaces: k,
|
|
6696
6698
|
alwaysFormat: b
|
|
6697
6699
|
} = e.interpolation;
|
|
6698
|
-
this.escape = r !== void 0 ? r : bn, this.escapeValue = o !== void 0 ? o : !0, this.useRawValueToEscape = a !== void 0 ? a : !1, this.prefix = i ?
|
|
6700
|
+
this.escape = r !== void 0 ? r : bn, this.escapeValue = o !== void 0 ? o : !0, this.useRawValueToEscape = a !== void 0 ? a : !1, this.prefix = i ? De(i) : n || "{{", this.suffix = s ? De(s) : u || "}}", this.formatSeparator = l || ",", this.unescapePrefix = p ? "" : c || "-", this.unescapeSuffix = this.unescapePrefix ? "" : p || "", this.nestingPrefix = g ? De(g) : f || De("$t("), this.nestingSuffix = _ ? De(_) : m || De(")"), this.nestingOptionsSeparator = y || ",", this.maxReplaces = k || 1e3, this.alwaysFormat = b !== void 0 ? b : !1, this.resetRegExp();
|
|
6699
6701
|
}
|
|
6700
6702
|
reset() {
|
|
6701
6703
|
this.options && this.init(this.options);
|
|
@@ -6811,7 +6813,7 @@ const Sn = (t) => {
|
|
|
6811
6813
|
formatName: e,
|
|
6812
6814
|
formatOptions: r
|
|
6813
6815
|
};
|
|
6814
|
-
},
|
|
6816
|
+
}, Ae = (t) => {
|
|
6815
6817
|
const e = {};
|
|
6816
6818
|
return (r, o, a) => {
|
|
6817
6819
|
let i = a;
|
|
@@ -6828,32 +6830,32 @@ class En {
|
|
|
6828
6830
|
constructor() {
|
|
6829
6831
|
let e = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
|
|
6830
6832
|
this.logger = ue.create("formatter"), this.options = e, this.formats = {
|
|
6831
|
-
number:
|
|
6833
|
+
number: Ae((r, o) => {
|
|
6832
6834
|
const a = new Intl.NumberFormat(r, {
|
|
6833
6835
|
...o
|
|
6834
6836
|
});
|
|
6835
6837
|
return (i) => a.format(i);
|
|
6836
6838
|
}),
|
|
6837
|
-
currency:
|
|
6839
|
+
currency: Ae((r, o) => {
|
|
6838
6840
|
const a = new Intl.NumberFormat(r, {
|
|
6839
6841
|
...o,
|
|
6840
6842
|
style: "currency"
|
|
6841
6843
|
});
|
|
6842
6844
|
return (i) => a.format(i);
|
|
6843
6845
|
}),
|
|
6844
|
-
datetime:
|
|
6846
|
+
datetime: Ae((r, o) => {
|
|
6845
6847
|
const a = new Intl.DateTimeFormat(r, {
|
|
6846
6848
|
...o
|
|
6847
6849
|
});
|
|
6848
6850
|
return (i) => a.format(i);
|
|
6849
6851
|
}),
|
|
6850
|
-
relativetime:
|
|
6852
|
+
relativetime: Ae((r, o) => {
|
|
6851
6853
|
const a = new Intl.RelativeTimeFormat(r, {
|
|
6852
6854
|
...o
|
|
6853
6855
|
});
|
|
6854
6856
|
return (i) => a.format(i, o.range || "day");
|
|
6855
6857
|
}),
|
|
6856
|
-
list:
|
|
6858
|
+
list: Ae((r, o) => {
|
|
6857
6859
|
const a = new Intl.ListFormat(r, {
|
|
6858
6860
|
...o
|
|
6859
6861
|
});
|
|
@@ -6871,7 +6873,7 @@ class En {
|
|
|
6871
6873
|
this.formats[e.toLowerCase().trim()] = r;
|
|
6872
6874
|
}
|
|
6873
6875
|
addCached(e, r) {
|
|
6874
|
-
this.formats[e.toLowerCase().trim()] =
|
|
6876
|
+
this.formats[e.toLowerCase().trim()] = Ae(r);
|
|
6875
6877
|
}
|
|
6876
6878
|
format(e, r, o) {
|
|
6877
6879
|
let a = arguments.length > 3 && arguments[3] !== void 0 ? arguments[3] : {};
|