Files
2026-01-09 19:24:41 +00:00

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