@empathyco/x-components
Version:
Empathy X Components
74 lines (71 loc) • 3.03 kB
JavaScript
import { defineComponent, provide, ref, computed, watch, h } from 'vue';
import { LIST_ITEMS_KEY, QUERY_KEY, HAS_MORE_ITEMS_KEY } from '../../../components/decorators/injection.consts.js';
import ItemsList from '../../../components/items-list.vue.js';
import { useState } from '../../../composables/use-state.js';
import { AnimationProp } from '../../../types/animation-prop.js';
import { searchXModule } from '../x-module.js';
/**
* It renders a {@link ItemsList} list with the results from {@link SearchState.results} by
* default.
*
* The component provides a default slot which wraps the whole component with the `results` bound.
*
* It also provides the slot result to customize the item, which is within the default slot, with
* the result bound.
*
* @public
*/
var _sfc_main = defineComponent({
name: 'ResultsList',
xModule: searchXModule.name,
props: {
/** Animation component that will be used to animate the results. */
animation: {
type: AnimationProp,
default: 'ul',
},
},
emits: ['UserReachedResultsListEnd'],
setup(props, { slots }) {
/**
* The results to render from the state.
*
* @remarks The results list are provided with `items` key. It can be
* concatenated with list items from components such as `BannersList`, `PromotedsList`,
* `BaseGrid` or any component that injects the list.
*/
const { query: searchQuery, totalResults, results: items, status: searchStatus, } = useState('search');
provide(LIST_ITEMS_KEY, items);
/** This query is updated only when the search request has succeeded. */
const providedQuery = ref('');
provide(QUERY_KEY, providedQuery);
/** Indicates if there are more available results that have not been injected. */
const hasMoreItems = computed(() => items.value.length < totalResults.value);
provide(HAS_MORE_ITEMS_KEY, hasMoreItems);
/**
* Updates the query to be provided to the child components
* when the search request has succeeded.
*
* @param status - The status of the search request.
*/
function updateQuery(status) {
if (status === 'success') {
providedQuery.value = searchQuery.value;
}
}
/**
* Watches the searchStatus and triggers updateQuery as callback
* when it changes.
*
* @param status - The status of the search request.
*/
watch(searchStatus, () => updateQuery(searchStatus.value), { immediate: true });
return () => {
const innerProps = { items: items.value, animation: props.animation };
// https://vue-land.github.io/faq/forwarding-slots#passing-all-slots
return slots.default?.(innerProps)[0] ?? h(ItemsList, innerProps, slots);
};
},
});
export { _sfc_main as default };
//# sourceMappingURL=results-list.vue.js.map