vuetify
Version:
Vue Material Component Framework
151 lines (149 loc) • 4.69 kB
JavaScript
// Composables
import { useLocale } from "../../../composables/index.js";
import { useProxiedModel } from "../../../composables/proxiedModel.js"; // Utilities
import { computed, inject, provide, toRef } from 'vue';
import { getObjectValueByPath, isEmpty, propsFactory } from "../../../util/index.js"; // Types
export const makeDataTableSortProps = propsFactory({
sortBy: {
type: Array,
default: () => []
},
customKeySort: Object,
multiSort: Boolean,
mustSort: Boolean
}, 'DataTable-sort');
const VDataTableSortSymbol = Symbol.for('vuetify:data-table-sort');
export function createSort(props) {
const sortBy = useProxiedModel(props, 'sortBy');
const mustSort = toRef(() => props.mustSort);
const multiSort = toRef(() => props.multiSort);
return {
sortBy,
mustSort,
multiSort
};
}
export function provideSort(options) {
const {
sortBy,
mustSort,
multiSort,
page
} = options;
const toggleSort = column => {
if (column.key == null) return;
let newSortBy = sortBy.value.map(x => ({
...x
})) ?? [];
const item = newSortBy.find(x => x.key === column.key);
if (!item) {
if (multiSort.value) {
newSortBy.push({
key: column.key,
order: 'asc'
});
} else {
newSortBy = [{
key: column.key,
order: 'asc'
}];
}
} else if (item.order === 'desc') {
if (mustSort.value && newSortBy.length === 1) {
item.order = 'asc';
} else {
newSortBy = newSortBy.filter(x => x.key !== column.key);
}
} else {
item.order = 'desc';
}
sortBy.value = newSortBy;
if (page) page.value = 1;
};
function isSorted(column) {
return !!sortBy.value.find(item => item.key === column.key);
}
const data = {
sortBy,
toggleSort,
isSorted
};
provide(VDataTableSortSymbol, data);
return data;
}
export function useSort() {
const data = inject(VDataTableSortSymbol);
if (!data) throw new Error('Missing sort!');
return data;
}
// TODO: abstract into project composable
export function useSortedItems(props, items, sortBy, options) {
const locale = useLocale();
const sortedItems = computed(() => {
if (!sortBy.value.length) return items.value;
return sortItems(items.value, sortBy.value, locale.current.value, {
transform: options?.transform,
sortFunctions: {
...props.customKeySort,
...options?.sortFunctions?.value
},
sortRawFunctions: options?.sortRawFunctions?.value
});
});
return {
sortedItems
};
}
export function sortItems(items, sortByItems, locale, options) {
const stringCollator = new Intl.Collator(locale, {
sensitivity: 'accent',
usage: 'sort'
});
const transformedItems = items.map(item => [item, options?.transform ? options.transform(item) : item]);
return transformedItems.sort((a, b) => {
for (let i = 0; i < sortByItems.length; i++) {
let hasCustomResult = false;
const sortKey = sortByItems[i].key;
const sortOrder = sortByItems[i].order ?? 'asc';
if (sortOrder === false) continue;
let sortA = getObjectValueByPath(a[1], sortKey);
let sortB = getObjectValueByPath(b[1], sortKey);
let sortARaw = a[0].raw;
let sortBRaw = b[0].raw;
if (sortOrder === 'desc') {
[sortA, sortB] = [sortB, sortA];
[sortARaw, sortBRaw] = [sortBRaw, sortARaw];
}
if (options?.sortRawFunctions?.[sortKey]) {
const customResult = options.sortRawFunctions[sortKey](sortARaw, sortBRaw);
if (customResult == null) continue;
hasCustomResult = true;
if (customResult) return customResult;
}
if (options?.sortFunctions?.[sortKey]) {
const customResult = options.sortFunctions[sortKey](sortA, sortB);
if (customResult == null) continue;
hasCustomResult = true;
if (customResult) return customResult;
}
if (hasCustomResult) continue;
// Dates should be compared numerically
if (sortA instanceof Date && sortB instanceof Date) {
return sortA.getTime() - sortB.getTime();
}
[sortA, sortB] = [sortA, sortB].map(s => s != null ? s.toString().toLocaleLowerCase() : s);
if (sortA !== sortB) {
if (isEmpty(sortA) && isEmpty(sortB)) return 0;
if (isEmpty(sortA)) return -1;
if (isEmpty(sortB)) return 1;
if (!isNaN(sortA) && !isNaN(sortB)) return Number(sortA) - Number(sortB);
return stringCollator.compare(sortA, sortB);
}
}
return 0;
}).map(_ref => {
let [item] = _ref;
return item;
});
}
//# sourceMappingURL=sort.js.map