vueless
Version:
Vue Styleless UI Component Library, powered by Tailwind CSS.
123 lines (99 loc) • 3.43 kB
text/typescript
import type { Option } from "../ui.dropdown-list/types.ts";
export function filterOptions(options: Option[], search: string, labelKey: string) {
if (!search) return options;
return options
.filter((option) => {
return interpolateLabel(option, labelKey).toLowerCase().includes(search.toLowerCase());
})
.sort((a, b) => {
const aOptionIndex = interpolateLabel(a, labelKey).indexOf(search);
const bOptionIndex = interpolateLabel(b, labelKey).indexOf(search);
return aOptionIndex - bOptionIndex;
});
}
export function filterGroups(
options: Option[],
search: string,
label: string,
groupValueKey: string,
groupLabelKey: string,
): Option[] {
return options
.map((option) => {
const group = option[groupValueKey];
if (Array.isArray(group)) {
return {
[groupLabelKey]: option[groupLabelKey],
[groupValueKey]: filterOptions(group, search, label),
};
}
})
.reduce((accumulator: Option[], group) => {
if (!group) return accumulator;
const groupValues = group[groupValueKey];
if (Array.isArray(groupValues) && groupValues.length) {
accumulator.push({ groupLabel: String(group[groupLabelKey] || "") });
return accumulator.concat(groupValues);
}
return accumulator;
}, []);
}
export function removeSelectedValues(
options: Option[],
selectedValues: (string | number)[],
valueKey: string,
groupValueKey?: string,
): Option[] {
if (!groupValueKey) {
return options.filter((option) => {
const value = option[valueKey];
return typeof value === "string" || typeof value === "number"
? !selectedValues.includes(value)
: false;
});
}
return options
.map((option) => {
if (!Array.isArray(option[groupValueKey])) return;
const filteredGroup = option[groupValueKey].filter((item) => {
const value = item[valueKey];
return typeof value === "string" || typeof value === "number"
? !selectedValues.includes(value) && !item.isSubGroup
: false;
});
return filteredGroup.length ? { ...option, [groupValueKey]: filteredGroup } : null;
})
.filter((option): option is Option => !!option);
}
export function getCurrentOption(
options: Option[],
selectedValue: string | number | Option,
valueKey: string,
groupValueKey?: string,
) {
const value = typeof selectedValue === "object" ? selectedValue?.[valueKey] : selectedValue;
const currentOption = groupValueKey
? getGroupOption(options, selectedValue, valueKey, groupValueKey)
: options.find((option) => option[valueKey] === value);
return currentOption || ({} as Option);
}
function getGroupOption(
options: Option[],
selectedValue: string | number | Option,
valueKey: string,
groupValueKey: string,
) {
const group = options.find((option) => {
return Array.isArray(option[groupValueKey])
? option[groupValueKey].find((value) => value[valueKey] === selectedValue)
: false;
});
const groupValues = group?.[groupValueKey] || [];
return Array.isArray(groupValues)
? groupValues.find((value) => value[valueKey] === selectedValue)
: undefined;
}
function interpolateLabel(option: Option, label: string) {
const interpolatedLabel = label ? option[label] : option;
return interpolatedLabel !== "object" ? String(interpolatedLabel) : "";
}