portalis-component
Version:
Component Library for Nuxt 3 using TailwindCSS
80 lines (79 loc) • 2.31 kB
JavaScript
import defu from "defu";
import { tryOnMounted } from "@vueuse/shared";
import { onFinishTyping, onStartTyping } from "../utils/use-on-typing.mjs";
import { onScrollBottom } from "../utils/use-on-scroll.mjs";
import { defineAdapter } from "./adapter.mjs";
import { ref, watch } from "#imports";
export default function defineAsyncAdapter(loadFn, deps, opts) {
const config = defu(opts, { perPage: 20, debounceTime: 500 });
return defineAdapter({
setup({ isLoading, keyword, menuEl, props, isLoadMore, isDone }) {
const options = ref([]);
const page = ref(1);
const isFinish = ref(false);
const isTyping = ref(false);
function load() {
isLoading.value = true;
loadFn(keyword.value, page.value, config.perPage, props.modelValue).then((result) => {
if (Array.isArray(result) && result.length > 0) {
options.value = [...options.value, ...result];
page.value = page.value + 1;
}
if (!Array.isArray(result) || result.length < config.perPage)
isFinish.value = true;
}).catch(console.error).finally(() => {
isLoading.value = false;
});
}
watch(isFinish, (val) => {
if (isDone !== void 0)
isDone.value = val;
});
function reset() {
isFinish.value = false;
page.value = 1;
options.value = [];
}
if (deps !== void 0) {
watch(deps, () => {
keyword.value = "";
reset();
load();
});
}
if (isLoadMore !== void 0) {
watch(isLoadMore, (val) => {
if (val) {
load();
isLoadMore.value = false;
}
});
}
tryOnMounted(() => {
load();
});
onStartTyping(keyword, () => {
isTyping.value = true;
reset();
});
onFinishTyping(
keyword,
() => {
isTyping.value = false;
load();
},
config.debounceTime
);
watch(isTyping, (value) => {
isLoading.value = value;
});
if (!props.isShowMore) {
onScrollBottom(menuEl, () => {
if (!isLoading.value && !isFinish.value)
load();
});
}
return options;
}
});
}