You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Seeing as the createWidgetMixin mixin does not work in a composition API environement, I created a composable which duplicates the functionality of that mixin. I thought I would share it with the community and also so that you guys can maybe add it to the library.
One difference is that the composable requires to pass "widgetParams" as a parameter whereas the mixin was retrieving it from the component instance.
I also added typescript to it, there is just one small issue whose cause I believe might be in the internals of instantsearch.
import type { Connector } from 'instantsearch.js/es/types/connector';
import type { WidgetDescription, UnknownWidgetParams } from 'instantsearch.js/es/types/widget';
import type InstantSearch from 'instantsearch.js/es/lib/InstantSearch';
import type { IndexWidget } from 'instantsearch.js/es/widgets/index/index';
/**
* This is a mixin of vue-instantsearch which was transformed into a composable to make it compatible with composition API.
* see https://github.com/algolia/instantsearch/blob/master/packages/vue-instantsearch/src/mixins/widget.js
* Also added typescript on top of it.
*
* @param widgetParams
* @param connector
* @param additionalProperties
*/
export default <TWidgetDescription extends WidgetDescription, TConnectorParams extends UnknownWidgetParams>(
widgetParams: ComputedRef<TConnectorParams>,
{ connector }: { connector: Connector<TWidgetDescription, TConnectorParams> },
additionalProperties = {}
): Ref<TWidgetDescription['renderState'] | null> => {
const instantSearchInstance = inject('$_ais_instantSearchInstance') as InstantSearch & {
__forceRender: (widget: IndexWidget, parentWidget: IndexWidget) => void | null;
};
const getParentIndex = inject('$_ais_getParentIndex', () => instantSearchInstance.mainIndex) as () => IndexWidget;
const state = ref<TWidgetDescription['renderState'] | null>();
const updateState = (updatedState = {}, isFirstRender: boolean): void => {
if (!isFirstRender) {
// Avoid updating the state on first render
// otherwise there will be a flash of placeholder data
state.value = updatedState;
}
};
if (typeof connector !== 'function') {
// eslint-disable-next-line no-console
console.warn(
`You are using the InstantSearch widget mixin, but didn't provide a connector.
While this is technically possible, and will give you access to the Helper,
it's not the recommended way of making custom components.
If you want to disable this message, pass { connector: true } to the mixin.
Read more on using connectors: https://alg.li/vue-custom`
);
}
const factory = connector(updateState, () => {
/** do nothing **/
});
let widget = { ...factory(widgetParams.value), ...additionalProperties };
getParentIndex().addWidgets([widget]);
if (instantSearchInstance._initialResults && !instantSearchInstance.started) {
if (typeof instantSearchInstance.__forceRender !== 'function') {
throw new TypeError(
'You are using server side rendering with <ais-instant-search> instead of <ais-instant-search-ssr>.'
);
}
// @ts-expect-error This seems to be an issue with internal types of instantsearch, probably missing as const.
instantSearchInstance.__forceRender(widget, getParentIndex());
}
onBeforeUnmount(() => {
if (widget) {
getParentIndex().removeWidgets([widget]);
}
});
watch(
widgetParams,
(nextWidgetParams) => {
state.value = null;
getParentIndex().removeWidgets([widget]);
widget = { ...factory(nextWidgetParams), ...additionalProperties };
getParentIndex().addWidgets([widget]);
},
{ deep: true }
);
return state;
};
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
Hello,
Seeing as the createWidgetMixin mixin does not work in a composition API environement, I created a composable which duplicates the functionality of that mixin. I thought I would share it with the community and also so that you guys can maybe add it to the library.
One difference is that the composable requires to pass "widgetParams" as a parameter whereas the mixin was retrieving it from the component instance.
I also added typescript to it, there is just one small issue whose cause I believe might be in the internals of instantsearch.
Beta Was this translation helpful? Give feedback.
All reactions