176 lines
5.9 KiB
JavaScript
176 lines
5.9 KiB
JavaScript
import {
|
|
getPropertyFromItem,
|
|
propsFactory,
|
|
wrapInArray
|
|
} from "./chunk-LZ5T2ERG.js";
|
|
import {
|
|
Fragment,
|
|
computed,
|
|
createBaseVNode,
|
|
normalizeClass,
|
|
shallowRef,
|
|
unref,
|
|
watchEffect
|
|
} from "./chunk-2MKFL3BX.js";
|
|
|
|
// node_modules/vuetify/lib/composables/filter.js
|
|
var defaultFilter = (value, query, item) => {
|
|
if (value == null || query == null) return -1;
|
|
if (!query.length) return 0;
|
|
value = value.toString().toLocaleLowerCase();
|
|
query = query.toString().toLocaleLowerCase();
|
|
const result = [];
|
|
let idx = value.indexOf(query);
|
|
while (~idx) {
|
|
result.push([idx, idx + query.length]);
|
|
idx = value.indexOf(query, idx + query.length);
|
|
}
|
|
return result.length ? result : -1;
|
|
};
|
|
function normaliseMatch(match, query) {
|
|
if (match == null || typeof match === "boolean" || match === -1) return;
|
|
if (typeof match === "number") return [[match, match + query.length]];
|
|
if (Array.isArray(match[0])) return match;
|
|
return [match];
|
|
}
|
|
var makeFilterProps = propsFactory({
|
|
customFilter: Function,
|
|
customKeyFilter: Object,
|
|
filterKeys: [Array, String],
|
|
filterMode: {
|
|
type: String,
|
|
default: "intersection"
|
|
},
|
|
noFilter: Boolean
|
|
}, "filter");
|
|
function filterItems(items, query, options) {
|
|
const array = [];
|
|
const filter = options?.default ?? defaultFilter;
|
|
const keys = options?.filterKeys ? wrapInArray(options.filterKeys) : false;
|
|
const customFiltersLength = Object.keys(options?.customKeyFilter ?? {}).length;
|
|
if (!items?.length) return array;
|
|
let lookAheadItem = null;
|
|
loop: for (let i = 0; i < items.length; i++) {
|
|
const [item, transformed = item] = wrapInArray(items[i]);
|
|
const customMatches = {};
|
|
const defaultMatches = {};
|
|
let match = -1;
|
|
if ((query || customFiltersLength > 0) && !options?.noFilter) {
|
|
let hasOnlyCustomFilters = false;
|
|
if (typeof item === "object") {
|
|
if (item.type === "divider" || item.type === "subheader") {
|
|
if (lookAheadItem?.type === "divider" && item.type === "subheader") {
|
|
array.push(lookAheadItem);
|
|
}
|
|
lookAheadItem = {
|
|
index: i,
|
|
matches: {},
|
|
type: item.type
|
|
};
|
|
continue;
|
|
}
|
|
const filterKeys = keys || Object.keys(transformed);
|
|
hasOnlyCustomFilters = filterKeys.length === customFiltersLength;
|
|
for (const key of filterKeys) {
|
|
const value = getPropertyFromItem(transformed, key);
|
|
const keyFilter = options?.customKeyFilter?.[key];
|
|
match = keyFilter ? keyFilter(value, query, item) : filter(value, query, item);
|
|
if (match !== -1 && match !== false) {
|
|
if (keyFilter) customMatches[key] = normaliseMatch(match, query);
|
|
else defaultMatches[key] = normaliseMatch(match, query);
|
|
} else if (options?.filterMode === "every") {
|
|
continue loop;
|
|
}
|
|
}
|
|
} else {
|
|
match = filter(item, query, item);
|
|
if (match !== -1 && match !== false) {
|
|
defaultMatches.title = normaliseMatch(match, query);
|
|
}
|
|
}
|
|
const defaultMatchesLength = Object.keys(defaultMatches).length;
|
|
const customMatchesLength = Object.keys(customMatches).length;
|
|
if (!defaultMatchesLength && !customMatchesLength) continue;
|
|
if (options?.filterMode === "union" && customMatchesLength !== customFiltersLength && !defaultMatchesLength) continue;
|
|
if (options?.filterMode === "intersection" && (customMatchesLength !== customFiltersLength || !defaultMatchesLength && customFiltersLength > 0 && !hasOnlyCustomFilters)) continue;
|
|
}
|
|
if (lookAheadItem) {
|
|
array.push(lookAheadItem);
|
|
lookAheadItem = null;
|
|
}
|
|
array.push({
|
|
index: i,
|
|
matches: {
|
|
...defaultMatches,
|
|
...customMatches
|
|
}
|
|
});
|
|
}
|
|
return array;
|
|
}
|
|
function useFilter(props, items, query, options) {
|
|
const filteredItems = shallowRef([]);
|
|
const filteredMatches = shallowRef(/* @__PURE__ */ new Map());
|
|
const transformedItems = computed(() => options?.transform ? unref(items).map((item) => [item, options.transform(item)]) : unref(items));
|
|
watchEffect(() => {
|
|
const _query = typeof query === "function" ? query() : unref(query);
|
|
const strQuery = typeof _query !== "string" && typeof _query !== "number" ? "" : String(_query);
|
|
const results = filterItems(transformedItems.value, strQuery, {
|
|
customKeyFilter: {
|
|
...props.customKeyFilter,
|
|
...unref(options?.customKeyFilter)
|
|
},
|
|
default: props.customFilter,
|
|
filterKeys: props.filterKeys,
|
|
filterMode: props.filterMode,
|
|
noFilter: props.noFilter
|
|
});
|
|
const originalItems = unref(items);
|
|
const _filteredItems = [];
|
|
const _filteredMatches = /* @__PURE__ */ new Map();
|
|
results.forEach((_ref) => {
|
|
let {
|
|
index,
|
|
matches
|
|
} = _ref;
|
|
const item = originalItems[index];
|
|
_filteredItems.push(item);
|
|
_filteredMatches.set(item.value, matches);
|
|
});
|
|
filteredItems.value = _filteredItems;
|
|
filteredMatches.value = _filteredMatches;
|
|
});
|
|
function getMatches(item) {
|
|
return filteredMatches.value.get(item.value);
|
|
}
|
|
return {
|
|
filteredItems,
|
|
filteredMatches,
|
|
getMatches
|
|
};
|
|
}
|
|
function highlightResult(name, text, matches) {
|
|
if (matches == null || !matches.length) return text;
|
|
return matches.map((match, i) => {
|
|
const start = i === 0 ? 0 : matches[i - 1][1];
|
|
const result = [createBaseVNode("span", {
|
|
"class": normalizeClass(`${name}__unmask`)
|
|
}, [text.slice(start, match[0])]), createBaseVNode("span", {
|
|
"class": normalizeClass(`${name}__mask`)
|
|
}, [text.slice(match[0], match[1])])];
|
|
if (i === matches.length - 1) {
|
|
result.push(createBaseVNode("span", {
|
|
"class": normalizeClass(`${name}__unmask`)
|
|
}, [text.slice(match[1])]));
|
|
}
|
|
return createBaseVNode(Fragment, null, [result]);
|
|
});
|
|
}
|
|
|
|
export {
|
|
makeFilterProps,
|
|
useFilter,
|
|
highlightResult
|
|
};
|
|
//# sourceMappingURL=chunk-RB6DAYHX.js.map
|