Skip to content

Commit e4f3158

Browse files
committed
feat(live-example): add support of connectors
1 parent e7976ad commit e4f3158

File tree

1 file changed

+120
-64
lines changed

1 file changed

+120
-64
lines changed
Lines changed: 120 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import instantsearch from "../../../index.js";
2-
import capitalize from 'lodash/capitalize';
2+
import capitalize from "lodash/capitalize";
33

44
window.instantsearch = instantsearch;
55
window.search = instantsearch({
@@ -18,77 +18,133 @@ const el = html => {
1818
return div;
1919
};
2020

21-
export default function bindRunExamples(codeSamples) {
22-
codeSamples.forEach((codeSample, index) => {
23-
if (codeSample.lastChild.innerText.indexOf('search.addWidget') !== 0) {
24-
return
21+
function initWidgetExample(codeSample, index) {
22+
const state = { IS_RUNNING: false };
23+
24+
const [, widgetName] = /widgets.(\S+)\(/g.exec(
25+
codeSample.lastChild.innerText
26+
);
27+
28+
// container for code sample live example
29+
const liveExampleContainer = createLiveExampleContainer(
30+
widgetName,
31+
"widget",
32+
index
33+
);
34+
35+
const runExample = function() {
36+
if (!state.IS_RUNNING) {
37+
state.IS_RUNNING = true;
38+
39+
// append widget container before running code
40+
codeSample.after(liveExampleContainer);
41+
42+
// replace `container` option with the generated one
43+
const codeToEval = codeSample.lastChild.innerText.replace(
44+
/container: \S+,?/,
45+
`container: "#live-example-${index}",`
46+
);
47+
48+
// execute code, display widget
49+
window.eval(codeToEval);
50+
appendDefaultSearchWidgets(index);
2551
}
52+
};
53+
54+
appendRunButton(codeSample, runExample);
55+
}
56+
57+
function initConnectorExample(codeSample, index) {
58+
const state = { IS_RUNNING: false };
59+
60+
const [, widgetName] = /the custom (\S+) widget/g.exec(
61+
codeSample.lastChild.innerText
62+
);
63+
64+
const liveExampleContainer = createLiveExampleContainer(
65+
widgetName,
66+
"connector",
67+
index
68+
);
69+
70+
const runExample = () => {
71+
if (!state.IS_RUNNING) {
72+
state.IS_RUNNING = true;
73+
74+
codeSample.after(liveExampleContainer);
2675

27-
const state = { RUNNING: false };
76+
const codeToEval = codeSample.lastChild.innerText.replace(
77+
/containerNode: \S+,?/,
78+
`containerNode: $("#live-example-${index}"),`
79+
);
2880

29-
const [, widgetName] = /widgets.(\S+)\(/g.exec(
30-
codeSample.lastChild.innerText
31-
);
81+
window.eval(codeToEval);
82+
appendDefaultSearchWidgets(index);
83+
}
84+
};
85+
86+
appendRunButton(codeSample, runExample);
87+
}
3288

33-
// container for code sample live example
34-
const liveExampleContainer = el(`
35-
<div class="live-example">
36-
<h3>${capitalize(widgetName)} widget example</h3>
37-
<div id="live-example-${index}"></div>
89+
function createLiveExampleContainer(name, type, index) {
90+
return el(`
91+
<div class="live-example">
92+
<h3>${capitalize(name)} ${type} example</h3>
93+
<div id="live-example-${index}"></div>
3894
39-
<div class="live-example-helpers">
40-
<h3>SearchBox & Hits</h3>
41-
<div id="search-box-container-${index}"></div>
42-
<div id="hits-container-${index}"></div>
43-
</div>
95+
<div class="live-example-helpers">
96+
<h3>SearchBox & Hits</h3>
97+
<div id="search-box-container-${index}"></div>
98+
<div id="hits-container-${index}"></div>
4499
</div>
45-
`);
46-
47-
const runExample = function() {
48-
if (!state.RUNNING) {
49-
state.RUNNING = true;
50-
51-
// append widget container before running code
52-
codeSample.after(liveExampleContainer);
53-
54-
// replace `container` option with the generated one
55-
const codeToEval = codeSample.lastChild.innerText.replace(
56-
/container: \S+,?/,
57-
`container: "#live-example-${index}",`
58-
);
59-
60-
// execute code, display widget
61-
window.eval(codeToEval);
62-
63-
// add default searchbox & hits
64-
search.addWidget(
65-
instantsearch.widgets.searchBox({
66-
container: `#search-box-container-${index}`,
67-
placeholder: "Search for products",
68-
autofocus: false
69-
})
70-
);
71-
72-
search.addWidget(
73-
instantsearch.widgets.hits({
74-
container: `#hits-container-${index}`,
75-
templates: {
76-
empty: "No results",
77-
item: "<strong>Hit {{objectID}}</strong>: {{{_highlightResult.name.value}}}"
78-
}
79-
})
80-
);
81-
82-
search.start();
100+
</div>
101+
`);
102+
}
103+
104+
function appendDefaultSearchWidgets(index) {
105+
// add default searchbox & hits
106+
search.addWidget(
107+
instantsearch.widgets.searchBox({
108+
container: `#search-box-container-${index}`,
109+
placeholder: "Search for products",
110+
autofocus: false
111+
})
112+
);
113+
114+
search.addWidget(
115+
instantsearch.widgets.hits({
116+
container: `#hits-container-${index}`,
117+
templates: {
118+
empty: "No results",
119+
item: "<strong>Hit {{objectID}}</strong>: {{{_highlightResult.name.value}}}"
83120
}
84-
};
121+
})
122+
);
123+
124+
search.start();
125+
}
85126

86-
// button with `Run` label
87-
const runBtn = document.createElement("button");
88-
runBtn.textContent = "Run";
89-
runBtn.style.marginRight = "10px";
90-
runBtn.onclick = runExample;
127+
function appendRunButton(codeSample, handler) {
128+
const runBtn = document.createElement("button");
129+
runBtn.textContent = "Run";
130+
runBtn.style.marginRight = "10px";
131+
runBtn.onclick = handler;
91132

92-
codeSample.firstChild.appendChild(runBtn);
133+
codeSample.firstChild.appendChild(runBtn);
134+
}
135+
136+
export default function bindRunExamples(codeSamples) {
137+
codeSamples.forEach((codeSample, index) => {
138+
const exampleContent = codeSample.lastChild.innerText;
139+
140+
// initialize examples for widget
141+
if (exampleContent.indexOf("search.addWidget") === 0) {
142+
initWidgetExample(codeSample, index);
143+
}
144+
145+
// initialize examples for connector, check we have the matching pattern
146+
if (/function renderFn\(\S+, isFirstRendering\) {/g.test(exampleContent)) {
147+
initConnectorExample(codeSample, index);
148+
}
93149
});
94150
}

0 commit comments

Comments
 (0)