Skip to content

Commit

Permalink
fix(instantsearch.js/facet-dropdown): use render instead of init (#436)
Browse files Browse the repository at this point in the history
  • Loading branch information
sarahdayan authored Feb 16, 2023
1 parent 335094c commit 43310ed
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 68 deletions.
4 changes: 2 additions & 2 deletions instantsearch.js/facet-dropdown/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ <h1 class="header-title">
<div id="pagination"></div>
</div>

<script src="https://cdn.jsdelivr.net/algoliasearch/3.32.0/algoliasearchLite.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/instantsearch.js@4.9.1"></script>
<script src="https://cdn.jsdelivr.net/npm/algoliasearch@4/dist/algoliasearch-lite.umd.js"></script>
<script src="https://cdn.jsdelivr.net/npm/instantsearch.js@4"></script>
<script src="./src/app.js"></script>
</body>
</html>
133 changes: 71 additions & 62 deletions instantsearch.js/facet-dropdown/src/Dropdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export function createDropdown(
const makeWidget = instantsearch.widgets.panel({
cssClasses,
templates: {
header: (options) => {
header: options => {
const { widgetParams } = options;

let text;
Expand All @@ -51,7 +51,7 @@ export function createDropdown(
: '';
// Get the number of refinements if the widget has `items`
const nbRefinements = (options.items || []).filter(
(item) => item.isRefined
item => item.isRefined
).length;
// Format the button text
text =
Expand All @@ -63,7 +63,7 @@ export function createDropdown(
classNames.push(buttonClassName);
} else if (typeof buttonClassName === 'function') {
classNames.push(buttonClassName(options));
} else if ((options.items || []).find((item) => item.isRefined)) {
} else if ((options.items || []).find(item => item.isRefined)) {
classNames.push(cssClasses.buttonRefined);
}

Expand All @@ -77,73 +77,80 @@ export function createDropdown(
},
})(baseWidget);

return (widgetParams) => {
return widgetParams => {
const widget = makeWidget(widgetParams);
let cleanUp;
let state = {};
let rootElem, headerElem, closeButtonElem;

const open = () => {
addClassName(rootElem, CLASS_OPENED);
// This 'click' event is still being propagated,
// so we add this event listener in the next tick.
// Otherwise, it will immediately close the panel again.
setTimeout(() => {
state.windowClickListener = event => {
// Close if the outside is clicked
if (!rootElem.contains(event.target)) {
close();
}
};
// Add an event listener when the panel is opened
window.addEventListener('click', state.windowClickListener);
}, 0);
};
const close = () => {
removeClassName(rootElem, CLASS_OPENED);
// Remove the event listener when the panel is closed
window.removeEventListener('click', state.windowClickListener);
delete state.windowClickListener;
};
const isOpened = () => hasClassName(rootElem, CLASS_OPENED);
const toggle = () => {
if (isOpened()) {
close();
} else {
open();
}
};

// Add a click listener to the header (button)
const buttonListener = event => {
if (!event.target.matches('.' + CLASS_BUTTON)) {
return;
}
toggle();
};

// Setup a clean-up function, which will be called in `dispose`.
const cleanUp = () => {
headerElem.removeEventListener('click', buttonListener);
if (state.windowClickListener) {
window.removeEventListener('click', state.windowClickListener);
}
};

// Return a modified version of the widget
return {
...widget,
$$widgetType: 'cmty.facetDropdown',
init: (options) => {
const rootElem = document
.querySelector(widgetParams.container)
.querySelector('.ais-Panel');
const headerElem = rootElem.querySelector('.ais-Panel-header');
const closeButtonElem = rootElem.querySelector(
'.' + CLASS_CLOSE_BUTTON
);

const open = () => {
addClassName(rootElem, CLASS_OPENED);
// This 'click' event is still being propagated,
// so we add this event listener in the next tick.
// Otherwise, it will immediately close the panel again.
setTimeout(() => {
state.windowClickListener = (event) => {
// Close if the outside is clicked
if (!rootElem.contains(event.target)) {
close();
}
};
// Add an event listener when the panel is opened
window.addEventListener('click', state.windowClickListener);
}, 0);
};
const close = () => {
removeClassName(rootElem, CLASS_OPENED);
// Remove the event listener when the panel is closed
window.removeEventListener('click', state.windowClickListener);
delete state.windowClickListener;
};
const isOpened = () => hasClassName(rootElem, CLASS_OPENED);
const toggle = () => {
if (isOpened()) {
close();
} else {
open();
}
};
render: options => {
if (!rootElem) {
rootElem = document
.querySelector(widgetParams.container)
.querySelector('.ais-Panel');
}

// Add a click listener to the header (button)
const buttonListener = (event) => {
if (!event.target.matches('.' + CLASS_BUTTON)) {
return;
}
toggle();
};
headerElem.addEventListener('click', buttonListener);
if (!headerElem) {
headerElem = rootElem.querySelector('.ais-Panel-header');

closeButtonElem.addEventListener('click', close);
headerElem.addEventListener('click', buttonListener);
}

// Setup a clean-up function, which will be called in `dispose`.
cleanUp = () => {
headerElem.removeEventListener('click', buttonListener);
if (state.windowClickListener) {
window.removeEventListener('click', state.windowClickListener);
}
};
if (!closeButtonElem) {
closeButtonElem = rootElem.querySelector('.' + CLASS_CLOSE_BUTTON);

closeButtonElem.addEventListener('click', close);
}

// Whenever uiState changes, it closes the panel.
options.instantSearchInstance.use(() => ({
Expand All @@ -160,12 +167,14 @@ export function createDropdown(
}
},
}));
return widget.init.call(widget, options);

return widget.render.call(widget, options);
},
dispose: (options) => {
dispose: options => {
if (typeof cleanUp === 'function') {
cleanUp();
}

return widget.dispose.call(widget, options);
},
};
Expand Down
6 changes: 2 additions & 4 deletions instantsearch.js/facet-dropdown/src/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,13 @@ const search = instantsearch({
const MOBILE_WIDTH = 375;

const brandDropdown = createDropdown(instantsearch.widgets.refinementList, {
// closeOnChange: true,
closeOnChange: () => window.innerWidth >= MOBILE_WIDTH,
cssClasses: { root: 'my-BrandDropdown' },
});

const refinementListDropdown = createDropdown(
instantsearch.widgets.refinementList,
{
// closeOnChange: true,
closeOnChange: () => window.innerWidth >= MOBILE_WIDTH,
}
);
Expand All @@ -44,13 +42,13 @@ const priceDropdown = createDropdown(instantsearch.widgets.rangeSlider, {
const priceMenuDropdown = createDropdown(instantsearch.widgets.numericMenu, {
buttonText({ items }) {
const refinedItem = (items || []).find(
(item) => item.label !== 'All' && item.isRefined
item => item.label !== 'All' && item.isRefined
);
return refinedItem ? `Price (${refinedItem.label})` : 'Price Menu';
},
buttonClassName({ items }) {
const isRefined = (items || []).find(
(item) => item.label !== 'All' && item.isRefined
item => item.label !== 'All' && item.isRefined
);
return isRefined && 'ais-Dropdown-button--refined';
},
Expand Down

0 comments on commit 43310ed

Please sign in to comment.