UNPKG

vuetify

Version:

Vue Material Component Framework

151 lines (149 loc) 4.69 kB
// 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