{"version":3,"file":"useSortable.mjs","sources":["../../../../../../src/components/va-data-table/hooks/useSortable.ts"],"sourcesContent":["import { PropType, computed, ref, Ref, watch, ExtractPropTypes, ComputedRef } from 'vue'\n\nimport { useThrottleFunction, useThrottleProps } from '../../../composables'\n\nimport type {\n  DataTableColumnInternal,\n  DataTableRow,\n  DataTableItem,\n  DataTableSortingOrder,\n  DataTableSortingOptions,\n} from '../types'\n\nexport const useSortableProps = {\n  ...useThrottleProps,\n  sortBy: { type: String as PropType<string | undefined> },\n  columnSorted: { type: Object as PropType<any | undefined> },\n  sortingOrder: { type: [String, null] as PropType<DataTableSortingOrder | undefined> },\n  disableClientSideSorting: { type: Boolean, default: false },\n}\n\nexport type TSortedArgs = { sortBy: string, sortingOrder: DataTableSortingOrder, items: DataTableItem[], itemsIndexes: number[] }\n\nexport type TSortableEmits = ((\n  event: 'update:sortBy' | 'update:sortingOrder' | 'sorted',\n  args: string | DataTableSortingOrder | TSortedArgs,\n) => void) & ((event: 'columnSorted', args: { columnName: string, value: DataTableSortingOrder, column: DataTableColumnInternal }) => void)\n\nexport type TSortIcon = 'va-sort-asc' | 'va-sort-desc' | 'va-unsorted'\n\nexport const useSortable = <Item extends DataTableRow>(\n  columns: Ref<DataTableColumnInternal[]>,\n  filteredRows: Ref<Item[]>,\n  props: ExtractPropTypes<typeof useSortableProps>,\n  emit: TSortableEmits,\n) => {\n  const sortByFallback = ref('')\n  const sortBySync = computed<string>({\n    get () {\n      if (props.sortBy === undefined) {\n        return sortByFallback.value\n      } else {\n        return props.sortBy\n      }\n    },\n\n    set (value) {\n      if (props.sortBy === undefined) {\n        sortByFallback.value = value\n      }\n\n      emit('update:sortBy', value)\n    },\n  })\n\n  const sortingOrderFallback = ref(null as DataTableSortingOrder)\n  const sortingOrderSync = computed<DataTableSortingOrder>({\n    get () {\n      if (props.sortingOrder === undefined) {\n        return sortingOrderFallback.value\n      } else {\n        return props.sortingOrder\n      }\n    },\n\n    set (value) {\n      if (props.sortingOrder === undefined) {\n        sortingOrderFallback.value = value\n      }\n\n      emit('update:sortingOrder', value)\n    },\n  })\n\n  const defaultSortingFn = (a: unknown, b: unknown) => {\n    if (typeof a === 'string' && typeof b === 'string') {\n      return a.localeCompare(b)\n    }\n\n    if (typeof a === 'number' && typeof b === 'number') {\n      return a - b\n    }\n\n    const aParsed = parseFloat(a as string)\n    const bParsed = parseFloat(b as string)\n\n    if (!isNaN(aParsed) && !isNaN(bParsed)) {\n      return aParsed - bParsed\n    }\n\n    // If one of them is a number, prioritize numbers\n    if (!isNaN(aParsed)) { return -1 }\n    if (!isNaN(bParsed)) { return 1 }\n\n    return 0\n  }\n\n  // sorts by string-value of a given row's cell (depending on by which column the table is sorted) if no sortingFn is\n  // provided. Otherwise uses that very sortingFn. If sortingOrder is `null` then restores the initial sorting order of\n  // the rows.\n  const sortedRows = computed(() => {\n    if (props.disableClientSideSorting) {\n      return filteredRows.value\n    }\n\n    if (filteredRows.value.length <= 1) {\n      return filteredRows.value\n    }\n\n    const columnIndex = columns.value.findIndex(\n      ({ name, sortable }) => sortBySync.value === name && sortable,\n    )\n    const column = columns.value[columnIndex]\n\n    if (!column) {\n      return filteredRows.value\n    }\n\n    const sortingOrderRatio = sortingOrderSync.value === 'desc' ? -1 : 1\n\n    return [...filteredRows.value].sort((a, b) => {\n      if (sortingOrderSync.value === null) {\n        return a.initialIndex - b.initialIndex\n      } else {\n        const firstSource = a.cells[columnIndex].source\n        const secondSource = b.cells[columnIndex].source\n\n        return sortingOrderRatio * (\n          typeof column.sortingFn === 'function'\n            ? column.sortingFn(firstSource, secondSource)\n            : defaultSortingFn(firstSource, secondSource)\n        )\n      }\n    })\n  })\n\n  // sort each time the sortBy or sortingOrder is changed (and also initially). Also if columns definitions are changed\n  // (because that potentially means that the user runtime-introduced a custom sorting function for a specific column)\n  watch(sortedRows, () => {\n    emit('sorted', {\n      sortBy: sortBySync.value,\n      sortingOrder: sortingOrderSync.value,\n      items: sortedRows.value.map(row => row.source),\n      itemsIndexes: sortedRows.value.map(row => row.initialIndex),\n    })\n  })\n\n  const getNextSortingOptionsValue = (value: DataTableSortingOrder, options: DataTableSortingOptions) => {\n    const index = options.findIndex((sortingValue) => sortingValue === value)\n\n    return index !== -1\n      ? options[(index + 1) % options.length]\n      : options[0]\n  }\n\n  // a function to invoke when a heading of the table is clicked.\n  // Sets the clicked heading's column as a one to sort by and toggles the sorting order from \"asc\" to \"desc\" to `null`\n  // (un-sorted) if the same column is clicked again or sets sorting order to \"asc\" if some other column is chosen.\n  function toggleSorting (column: DataTableColumnInternal) {\n    let value: DataTableSortingOrder\n    if (column.name === sortBySync.value) {\n      value = getNextSortingOptionsValue(sortingOrderSync.value, column.sortingOptions)\n    } else {\n      sortBySync.value = column.name\n      value = column.sortingOptions[0]\n    }\n\n    sortingOrderSync.value = value\n    emit('columnSorted', { columnName: column.name, value, column })\n  }\n\n  const toggleSortingThrottled = useThrottleFunction(toggleSorting, props)\n\n  const sortingOrderIconName = computed(() => {\n    return sortingOrderSync.value === 'asc'\n      ? 'va-sort-asc'\n      : sortingOrderSync.value === 'desc'\n        ? 'va-sort-desc'\n        : 'va-unsorted'\n  }) as ComputedRef<TSortIcon>\n\n  return {\n    sortBySync,\n    sortingOrderSync,\n    toggleSorting: toggleSortingThrottled,\n    sortedRows,\n    sortingOrderIconName,\n  }\n}\n"],"names":[],"mappings":"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"}