Skip to content
This repository has been archived by the owner on Dec 30, 2022. It is now read-only.

Commit

Permalink
look ma, no slots!
Browse files Browse the repository at this point in the history
  • Loading branch information
Haroenv committed Mar 10, 2021
1 parent b2e3b88 commit 8b945a7
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 28 deletions.
Original file line number Diff line number Diff line change
@@ -1,20 +1,5 @@
<template>
<div
class="ais-DynamicWidgets"
v-show="state"
>
<div
class="ais-DynamicWidgets-widget"
v-for="attribute in attributesToRender"
:key="attribute"
>
<slot :name="attribute" />
</div>
</div>
</template>

<script>
import { createWidgetMixin } from '../mixins/widget';

function getAttribute(widget, initOptions) {
try {
const { widgetParams } = widget.getWidgetRenderState(initOptions);
Expand Down Expand Up @@ -119,7 +104,31 @@ const connectDynamicWidgets = function connectDynamicWidgets(
};
};

function getVueAttribute(vnode) {
if (!vnode.componentOptions) {
return undefined;
}

if (vnode.componentOptions.propsData.attribute) {
return vnode.componentOptions.propsData.attribute;
}
if (Array.isArray(vnode.componentOptions.propsData.attributes)) {
return vnode.componentOptions.propsData.attributes[0];
}

if (Array.isArray(vnode.componentOptions.children)) {
// return first child with a truthy attribute
return vnode.componentOptions.children.reduce(
(acc, curr) => (acc ? acc : getVueAttribute(curr)),
undefined
);
}

return undefined;
}

export default {
name: 'AisDynamicWidgets',
mixins: [createWidgetMixin({ connector: connectDynamicWidgets })],
props: {
transformItems: {
Expand All @@ -129,14 +138,28 @@ export default {
},
},
},
render(createElement) {
if (!this.state) {
return createElement(
'div',
{ attrs: { hidden: true } },
this.$slots.default
);
}

const components = new Map();
this.$slots.default.forEach(vnode => {
const attribute = getVueAttribute(vnode);
if (attribute) components.set(attribute, vnode);
});

return createElement(
'div',
{},
this.state.attributesToRender.map(attribute => components.get(attribute))

This comment has been minimized.

Copy link
@eunjae-lee

eunjae-lee Mar 11, 2021

Contributor

cool

);
},
computed: {
attributesToRender() {
if (this.state) {
return this.state.attributesToRender;
}
// render all widgets (hidden) before first render
return Object.keys(this.$slots);
},
widgetParams() {
return {
transformItems: this.transformItems,
Expand All @@ -146,4 +169,3 @@ export default {
},
},
};
</script>
2 changes: 1 addition & 1 deletion src/widgets.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,4 @@ export {
} from './components/ToggleRefinement.vue';
export { default as AisVoiceSearch } from './components/VoiceSearch.vue';
export { default as AisRelevantSort } from './components/RelevantSort.vue';
export { default as AisDynamicWidgets } from './components/DynamicWidgets.vue';
export { default as AisDynamicWidgets } from './components/DynamicWidgets';
6 changes: 3 additions & 3 deletions stories/DynamicWidgets.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ storiesOf('ais-dynamic-widgets', module)
.add('simple usage', () => ({
template: `
<ais-dynamic-widgets :transform-items="transformItems">
<ais-refinement-list slot="brand" attribute="brand"></ais-refinement-list>
<ais-menu slot="categories" attribute="categories"></ais-menu>
<ais-panel slot="hierarchicalCategories.lvl0">
<ais-refinement-list attribute="brand"></ais-refinement-list>
<ais-menu attribute="categories"></ais-menu>
<ais-panel>
<template slot="header">hierarchy</template>
<ais-hierarchical-menu :attributes="hierarchicalCategories"></ais-hierarchical-menu>
</ais-panel>
Expand Down

0 comments on commit 8b945a7

Please sign in to comment.