@tanstack/table-core 9.0.0-beta.46 → 9.0.0-beta.48

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (212) hide show
  1. package/dist/core/row-models/coreRowModelsFeature.types.d.cts +1 -1
  2. package/dist/core/row-models/coreRowModelsFeature.types.d.ts +1 -1
  3. package/dist/core/row-models/coreRowModelsFeature.utils.cjs +1 -1
  4. package/dist/core/row-models/coreRowModelsFeature.utils.cjs.map +1 -1
  5. package/dist/core/row-models/coreRowModelsFeature.utils.d.cts +1 -1
  6. package/dist/core/row-models/coreRowModelsFeature.utils.d.ts +1 -1
  7. package/dist/core/row-models/coreRowModelsFeature.utils.js +1 -1
  8. package/dist/core/row-models/coreRowModelsFeature.utils.js.map +1 -1
  9. package/dist/features/aggregation/aggregationFeature.cjs +38 -0
  10. package/dist/features/aggregation/aggregationFeature.cjs.map +1 -0
  11. package/dist/features/aggregation/aggregationFeature.d.cts +10 -0
  12. package/dist/features/aggregation/aggregationFeature.d.ts +10 -0
  13. package/dist/features/aggregation/aggregationFeature.js +38 -0
  14. package/dist/features/aggregation/aggregationFeature.js.map +1 -0
  15. package/dist/features/aggregation/aggregationFeature.types.cjs +13 -0
  16. package/dist/features/aggregation/aggregationFeature.types.cjs.map +1 -0
  17. package/dist/features/aggregation/aggregationFeature.types.d.cts +172 -0
  18. package/dist/features/aggregation/aggregationFeature.types.d.ts +172 -0
  19. package/dist/features/aggregation/aggregationFeature.types.js +12 -0
  20. package/dist/features/aggregation/aggregationFeature.types.js.map +1 -0
  21. package/dist/features/aggregation/aggregationFeature.utils.cjs +198 -0
  22. package/dist/features/aggregation/aggregationFeature.utils.cjs.map +1 -0
  23. package/dist/features/aggregation/aggregationFeature.utils.d.cts +33 -0
  24. package/dist/features/aggregation/aggregationFeature.utils.d.ts +33 -0
  25. package/dist/features/aggregation/aggregationFeature.utils.js +192 -0
  26. package/dist/features/aggregation/aggregationFeature.utils.js.map +1 -0
  27. package/dist/features/aggregation/aggregationFns.cjs +240 -0
  28. package/dist/features/aggregation/aggregationFns.cjs.map +1 -0
  29. package/dist/features/aggregation/aggregationFns.d.cts +67 -0
  30. package/dist/features/aggregation/aggregationFns.d.ts +67 -0
  31. package/dist/features/aggregation/aggregationFns.js +229 -0
  32. package/dist/features/aggregation/aggregationFns.js.map +1 -0
  33. package/dist/features/column-filtering/columnFilteringFeature.types.d.cts +43 -3
  34. package/dist/features/column-filtering/columnFilteringFeature.types.d.ts +43 -3
  35. package/dist/features/column-filtering/columnFilteringFeature.utils.cjs +18 -9
  36. package/dist/features/column-filtering/columnFilteringFeature.utils.cjs.map +1 -1
  37. package/dist/features/column-filtering/columnFilteringFeature.utils.d.cts +6 -2
  38. package/dist/features/column-filtering/columnFilteringFeature.utils.d.ts +6 -2
  39. package/dist/features/column-filtering/columnFilteringFeature.utils.js +18 -9
  40. package/dist/features/column-filtering/columnFilteringFeature.utils.js.map +1 -1
  41. package/dist/features/column-filtering/createFilteredRowModel.cjs +7 -2
  42. package/dist/features/column-filtering/createFilteredRowModel.cjs.map +1 -1
  43. package/dist/features/column-filtering/createFilteredRowModel.d.cts +6 -2
  44. package/dist/features/column-filtering/createFilteredRowModel.d.ts +6 -2
  45. package/dist/features/column-filtering/createFilteredRowModel.js +7 -2
  46. package/dist/features/column-filtering/createFilteredRowModel.js.map +1 -1
  47. package/dist/features/column-filtering/filterFns.cjs +399 -0
  48. package/dist/features/column-filtering/filterFns.cjs.map +1 -0
  49. package/dist/features/column-filtering/filterFns.d.cts +210 -0
  50. package/dist/features/column-filtering/filterFns.d.ts +210 -0
  51. package/dist/features/column-filtering/filterFns.js +375 -0
  52. package/dist/features/column-filtering/filterFns.js.map +1 -0
  53. package/dist/features/column-grouping/columnGroupingFeature.cjs +3 -12
  54. package/dist/features/column-grouping/columnGroupingFeature.cjs.map +1 -1
  55. package/dist/features/column-grouping/columnGroupingFeature.d.cts +1 -1
  56. package/dist/features/column-grouping/columnGroupingFeature.d.ts +1 -1
  57. package/dist/features/column-grouping/columnGroupingFeature.js +4 -13
  58. package/dist/features/column-grouping/columnGroupingFeature.js.map +1 -1
  59. package/dist/features/column-grouping/columnGroupingFeature.types.d.cts +6 -49
  60. package/dist/features/column-grouping/columnGroupingFeature.types.d.ts +6 -49
  61. package/dist/features/column-grouping/columnGroupingFeature.utils.cjs +0 -50
  62. package/dist/features/column-grouping/columnGroupingFeature.utils.cjs.map +1 -1
  63. package/dist/features/column-grouping/columnGroupingFeature.utils.d.cts +2 -39
  64. package/dist/features/column-grouping/columnGroupingFeature.utils.d.ts +2 -39
  65. package/dist/features/column-grouping/columnGroupingFeature.utils.js +2 -49
  66. package/dist/features/column-grouping/columnGroupingFeature.utils.js.map +1 -1
  67. package/dist/features/column-grouping/createGroupedRowModel.cjs +23 -13
  68. package/dist/features/column-grouping/createGroupedRowModel.cjs.map +1 -1
  69. package/dist/features/column-grouping/createGroupedRowModel.d.cts +2 -3
  70. package/dist/features/column-grouping/createGroupedRowModel.d.ts +2 -3
  71. package/dist/features/column-grouping/createGroupedRowModel.js +25 -15
  72. package/dist/features/column-grouping/createGroupedRowModel.js.map +1 -1
  73. package/dist/features/global-filtering/globalFilteringFeature.utils.cjs +4 -2
  74. package/dist/features/global-filtering/globalFilteringFeature.utils.cjs.map +1 -1
  75. package/dist/features/global-filtering/globalFilteringFeature.utils.d.cts +2 -6
  76. package/dist/features/global-filtering/globalFilteringFeature.utils.d.ts +2 -6
  77. package/dist/features/global-filtering/globalFilteringFeature.utils.js +4 -2
  78. package/dist/features/global-filtering/globalFilteringFeature.utils.js.map +1 -1
  79. package/dist/features/row-sorting/createSortedRowModel.cjs +6 -2
  80. package/dist/features/row-sorting/createSortedRowModel.cjs.map +1 -1
  81. package/dist/features/row-sorting/createSortedRowModel.d.cts +6 -2
  82. package/dist/features/row-sorting/createSortedRowModel.d.ts +6 -2
  83. package/dist/features/row-sorting/createSortedRowModel.js +6 -2
  84. package/dist/features/row-sorting/createSortedRowModel.js.map +1 -1
  85. package/dist/features/row-sorting/rowSortingFeature.types.d.cts +32 -3
  86. package/dist/features/row-sorting/rowSortingFeature.types.d.ts +32 -3
  87. package/dist/features/row-sorting/rowSortingFeature.utils.cjs +20 -5
  88. package/dist/features/row-sorting/rowSortingFeature.utils.cjs.map +1 -1
  89. package/dist/features/row-sorting/rowSortingFeature.utils.js +20 -5
  90. package/dist/features/row-sorting/rowSortingFeature.utils.js.map +1 -1
  91. package/dist/{fns → features/row-sorting}/sortFns.cjs +69 -22
  92. package/dist/features/row-sorting/sortFns.cjs.map +1 -0
  93. package/dist/features/row-sorting/sortFns.d.cts +98 -0
  94. package/dist/features/row-sorting/sortFns.d.ts +98 -0
  95. package/dist/{fns → features/row-sorting}/sortFns.js +69 -23
  96. package/dist/features/row-sorting/sortFns.js.map +1 -0
  97. package/dist/features/stockFeatures.cjs +2 -0
  98. package/dist/features/stockFeatures.cjs.map +1 -1
  99. package/dist/features/stockFeatures.d.cts +2 -0
  100. package/dist/features/stockFeatures.d.ts +2 -0
  101. package/dist/features/stockFeatures.js +2 -0
  102. package/dist/features/stockFeatures.js.map +1 -1
  103. package/dist/helpers/tableFeatures.cjs +5 -4
  104. package/dist/helpers/tableFeatures.cjs.map +1 -1
  105. package/dist/helpers/tableFeatures.d.cts +5 -4
  106. package/dist/helpers/tableFeatures.d.ts +5 -4
  107. package/dist/helpers/tableFeatures.js +5 -4
  108. package/dist/helpers/tableFeatures.js.map +1 -1
  109. package/dist/index.cjs +18 -3
  110. package/dist/index.d.cts +10 -8
  111. package/dist/index.d.ts +10 -8
  112. package/dist/index.js +6 -4
  113. package/dist/static-functions.cjs +8 -3
  114. package/dist/static-functions.d.cts +3 -2
  115. package/dist/static-functions.d.ts +3 -2
  116. package/dist/static-functions.js +3 -2
  117. package/dist/types/Cell.d.cts +3 -1
  118. package/dist/types/Cell.d.ts +3 -1
  119. package/dist/types/Column.d.cts +4 -2
  120. package/dist/types/Column.d.ts +4 -2
  121. package/dist/types/ColumnDef.d.cts +5 -3
  122. package/dist/types/ColumnDef.d.ts +5 -3
  123. package/dist/types/Row.d.cts +3 -1
  124. package/dist/types/Row.d.ts +3 -1
  125. package/dist/types/RowModel.d.cts +1 -1
  126. package/dist/types/RowModel.d.ts +1 -1
  127. package/dist/types/RowModelFns.d.cts +3 -3
  128. package/dist/types/RowModelFns.d.ts +3 -3
  129. package/dist/types/Table.d.cts +1 -1
  130. package/dist/types/Table.d.ts +1 -1
  131. package/dist/types/TableFeatures.d.cts +19 -11
  132. package/dist/types/TableFeatures.d.ts +19 -11
  133. package/dist/types/TableOptions.d.cts +5 -3
  134. package/dist/types/TableOptions.d.ts +5 -3
  135. package/dist/types/TableState.d.cts +1 -1
  136. package/dist/types/TableState.d.ts +1 -1
  137. package/dist/types/type-utils.d.cts +8 -1
  138. package/dist/types/type-utils.d.ts +8 -1
  139. package/dist/worker/initTableWorker.cjs.map +1 -1
  140. package/dist/worker/initTableWorker.js.map +1 -1
  141. package/package.json +1 -1
  142. package/skills/aggregation/SKILL.md +131 -0
  143. package/skills/api-not-found/SKILL.md +1 -1
  144. package/skills/client-vs-server/SKILL.md +1 -1
  145. package/skills/column-faceting/SKILL.md +11 -5
  146. package/skills/column-filtering/SKILL.md +8 -3
  147. package/skills/column-ordering/SKILL.md +1 -1
  148. package/skills/column-pinning/SKILL.md +1 -1
  149. package/skills/column-resizing/SKILL.md +1 -1
  150. package/skills/column-sizing/SKILL.md +1 -1
  151. package/skills/column-visibility/SKILL.md +1 -1
  152. package/skills/core/SKILL.md +1 -1
  153. package/skills/custom-features/SKILL.md +1 -1
  154. package/skills/expanding/SKILL.md +1 -1
  155. package/skills/global-filtering/SKILL.md +3 -3
  156. package/skills/grouping/SKILL.md +12 -13
  157. package/skills/migrate-v8-to-v9/SKILL.md +21 -8
  158. package/skills/pagination/SKILL.md +1 -1
  159. package/skills/row-pinning/SKILL.md +1 -1
  160. package/skills/row-selection/SKILL.md +1 -1
  161. package/skills/sorting/SKILL.md +9 -3
  162. package/skills/table-features/SKILL.md +19 -13
  163. package/skills/typescript/SKILL.md +1 -1
  164. package/src/core/row-models/coreRowModelsFeature.utils.ts +1 -1
  165. package/src/features/aggregation/aggregationFeature.ts +59 -0
  166. package/src/features/aggregation/aggregationFeature.types.ts +312 -0
  167. package/src/features/aggregation/aggregationFeature.utils.ts +401 -0
  168. package/src/features/aggregation/aggregationFns.ts +336 -0
  169. package/src/features/column-filtering/columnFilteringFeature.types.ts +61 -1
  170. package/src/features/column-filtering/columnFilteringFeature.utils.ts +33 -19
  171. package/src/features/column-filtering/createFilteredRowModel.ts +13 -3
  172. package/src/features/column-filtering/filterFns.ts +533 -0
  173. package/src/features/column-grouping/columnGroupingFeature.ts +1 -20
  174. package/src/features/column-grouping/columnGroupingFeature.types.ts +4 -86
  175. package/src/features/column-grouping/columnGroupingFeature.utils.ts +1 -88
  176. package/src/features/column-grouping/createGroupedRowModel.ts +32 -38
  177. package/src/features/global-filtering/globalFilteringFeature.utils.ts +9 -1
  178. package/src/features/row-sorting/createSortedRowModel.ts +6 -2
  179. package/src/features/row-sorting/rowSortingFeature.types.ts +54 -2
  180. package/src/features/row-sorting/rowSortingFeature.utils.ts +46 -14
  181. package/src/{fns → features/row-sorting}/sortFns.ts +95 -81
  182. package/src/features/stockFeatures.ts +3 -0
  183. package/src/helpers/tableFeatures.ts +5 -4
  184. package/src/index.ts +7 -8
  185. package/src/static-functions.ts +1 -0
  186. package/src/types/Cell.ts +2 -0
  187. package/src/types/Column.ts +3 -1
  188. package/src/types/ColumnDef.ts +6 -3
  189. package/src/types/Row.ts +2 -0
  190. package/src/types/RowModelFns.ts +3 -3
  191. package/src/types/TableFeatures.ts +19 -11
  192. package/src/types/TableOptions.ts +5 -1
  193. package/src/types/type-utils.ts +8 -0
  194. package/src/worker/initTableWorker.ts +1 -1
  195. package/dist/fns/aggregationFns.cjs +0 -163
  196. package/dist/fns/aggregationFns.cjs.map +0 -1
  197. package/dist/fns/aggregationFns.d.cts +0 -85
  198. package/dist/fns/aggregationFns.d.ts +0 -85
  199. package/dist/fns/aggregationFns.js +0 -153
  200. package/dist/fns/aggregationFns.js.map +0 -1
  201. package/dist/fns/filterFns.cjs +0 -242
  202. package/dist/fns/filterFns.cjs.map +0 -1
  203. package/dist/fns/filterFns.d.cts +0 -178
  204. package/dist/fns/filterFns.d.ts +0 -178
  205. package/dist/fns/filterFns.js +0 -226
  206. package/dist/fns/filterFns.js.map +0 -1
  207. package/dist/fns/sortFns.cjs.map +0 -1
  208. package/dist/fns/sortFns.d.cts +0 -65
  209. package/dist/fns/sortFns.d.ts +0 -65
  210. package/dist/fns/sortFns.js.map +0 -1
  211. package/src/fns/aggregationFns.ts +0 -245
  212. package/src/fns/filterFns.ts +0 -455
@@ -1 +1 @@
1
- {"version":3,"file":"columnFilteringFeature.utils.js","names":[],"sources":["../../../src/features/column-filtering/columnFilteringFeature.utils.ts"],"sourcesContent":["import { cloneState, functionalUpdate, isFunction } from '../../utils'\nimport type { CellData, RowData, Updater } from '../../types/type-utils'\nimport type { TableFeatures } from '../../types/TableFeatures'\nimport type { Table_Internal } from '../../types/Table'\nimport type { Column_Internal } from '../../types/Column'\nimport type {\n ColumnFiltersState,\n FilterFn,\n} from './columnFilteringFeature.types'\n\n/**\n * Creates the default column filter state.\n *\n * The feature default is an empty array, meaning no column filters are active.\n * Reset APIs use this value when `defaultState` is `true`.\n *\n * @example\n * ```ts\n * const filters = getDefaultColumnFiltersState()\n * ```\n */\nexport function getDefaultColumnFiltersState(): ColumnFiltersState {\n return []\n}\n\n/**\n * Chooses a built-in filter function from the column's first core row value.\n *\n * Strings use `includesString`, numbers use `inNumberRange`, booleans and\n * objects use `equals`, arrays use `arrIncludes`, and unknown values fall back\n * to `weakEquals`.\n *\n * @example\n * ```ts\n * const filterFn = column_getAutoFilterFn(column)\n * ```\n */\nexport function column_getAutoFilterFn<\n TFeatures extends TableFeatures,\n TData extends RowData,\n TValue extends CellData = CellData,\n>(column: Column_Internal<TFeatures, TData, TValue>) {\n const filterFns: Record<string, FilterFn<TFeatures, TData>> | undefined =\n column.table._rowModelFns.filterFns\n\n const firstRow = column.table.getCoreRowModel().flatRows[0]\n\n const value = firstRow ? firstRow.getValue(column.id) : undefined\n\n if (typeof value === 'string') {\n return filterFns?.includesString\n }\n\n if (typeof value === 'number') {\n return filterFns?.inNumberRange\n }\n\n if (typeof value === 'boolean') {\n return filterFns?.equals\n }\n\n if (Array.isArray(value)) {\n return filterFns?.arrIncludes\n }\n\n if (value !== null && typeof value === 'object') {\n return filterFns?.equals\n }\n\n return filterFns?.weakEquals\n}\n\n/**\n * Resolves the filter function configured for a column.\n *\n * Function-valued `columnDef.filterFn` is returned directly, `'auto'` delegates\n * to `column_getAutoFilterFn`, and string values are looked up in the table's\n * filter function registry.\n *\n * @example\n * ```ts\n * const filterFn = column_getFilterFn(column)\n * ```\n */\nexport function column_getFilterFn<\n TFeatures extends TableFeatures,\n TData extends RowData,\n TValue extends CellData = CellData,\n>(\n column: Column_Internal<TFeatures, TData, TValue>,\n): FilterFn<TFeatures, TData> | undefined {\n let filterFn = null\n const filterFns: Record<string, FilterFn<TFeatures, TData>> | undefined =\n column.table._rowModelFns.filterFns\n filterFn = isFunction(column.columnDef.filterFn)\n ? column.columnDef.filterFn\n : column.columnDef.filterFn === 'auto'\n ? column_getAutoFilterFn(column)\n : filterFns?.[column.columnDef.filterFn as string]\n\n if (process.env.NODE_ENV === 'development' && !filterFn) {\n console.warn(\n `Could not find a valid 'column.filterFn' for column with the ID: ${column.id}.`,\n )\n }\n\n return filterFn ?? undefined\n}\n\n/**\n * Checks whether column filtering is enabled for this accessor column.\n *\n * The column must have an accessor and filtering must be enabled by the column\n * definition, `enableColumnFilters`, and the table-wide `enableFilters` option.\n *\n * @example\n * ```ts\n * const canFilter = column_getCanFilter(column)\n * ```\n */\nexport function column_getCanFilter<\n TFeatures extends TableFeatures,\n TData extends RowData,\n TValue extends CellData = CellData,\n>(column: Column_Internal<TFeatures, TData, TValue>) {\n return (\n (column.columnDef.enableColumnFilter ?? true) &&\n (column.table.options.enableColumnFilters ?? true) &&\n (column.table.options.enableFilters ?? true) &&\n !!column.accessorFn\n )\n}\n\n/**\n * Checks whether this column currently has an entry in `state.columnFilters`.\n *\n * This only reflects filter state presence; it does not indicate whether the\n * filter removes any rows.\n *\n * @example\n * ```ts\n * const isFiltered = column_getIsFiltered(column)\n * ```\n */\nexport function column_getIsFiltered<\n TFeatures extends TableFeatures,\n TData extends RowData,\n TValue extends CellData = CellData,\n>(column: Column_Internal<TFeatures, TData, TValue>) {\n return column_getFilterIndex(column) > -1\n}\n\n/**\n * Reads this column's current filter value from `state.columnFilters`.\n *\n * Missing filter entries return `undefined`.\n *\n * @example\n * ```ts\n * const value = column_getFilterValue(column)\n * ```\n */\nexport function column_getFilterValue<\n TFeatures extends TableFeatures,\n TData extends RowData,\n TValue extends CellData = CellData,\n>(column: Column_Internal<TFeatures, TData, TValue>) {\n return column.table.atoms.columnFilters\n ?.get()\n ?.find((d) => d.id === column.id)?.value\n}\n\n/**\n * Finds this column's position in the ordered `state.columnFilters` array.\n *\n * The result is `-1` when the column has no active filter.\n *\n * @example\n * ```ts\n * const index = column_getFilterIndex(column)\n * ```\n */\nexport function column_getFilterIndex<\n TFeatures extends TableFeatures,\n TData extends RowData,\n TValue extends CellData = CellData,\n>(column: Column_Internal<TFeatures, TData, TValue>): number {\n return (\n column.table.atoms.columnFilters\n ?.get()\n ?.findIndex((d) => d.id === column.id) ?? -1\n )\n}\n\n/**\n * Adds, updates, or removes this column's filter value.\n *\n * The incoming value may be an updater. After resolution, `autoRemove` rules\n * decide whether the filter should be removed instead of stored.\n *\n * @example\n * ```ts\n * column_setFilterValue(column, (old) => String(old ?? '').trim())\n * ```\n */\nexport function column_setFilterValue<\n TFeatures extends TableFeatures,\n TData extends RowData,\n TValue extends CellData = CellData,\n>(column: Column_Internal<TFeatures, TData, TValue>, value: any) {\n table_setColumnFilters(column.table, (old) => {\n const filterFn = column_getFilterFn(column)\n const previousFilter = old.find((d) => d.id === column.id)\n\n const newFilter = functionalUpdate(\n value,\n previousFilter ? previousFilter.value : undefined,\n )\n\n if (shouldAutoRemoveFilter(filterFn, newFilter, column)) {\n return old.filter((d) => d.id !== column.id)\n }\n\n const newFilterObj = { id: column.id, value: newFilter }\n\n if (previousFilter) {\n return old.map((d) => {\n if (d.id === column.id) {\n return newFilterObj\n }\n return d\n })\n }\n\n if (old.length) {\n return [...old, newFilterObj]\n }\n\n return [newFilterObj]\n })\n}\n\n/**\n * Routes a column filter updater through the table's filter change handler.\n *\n * The resolved filters are cleaned before they are emitted: filters for known\n * columns are removed when their filter function says the value should be\n * auto-removed.\n *\n * @example\n * ```ts\n * table_setColumnFilters(table, (old) => old.filter((filter) => filter.id !== 'age'))\n * ```\n */\nexport function table_setColumnFilters<\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(\n table: Table_Internal<TFeatures, TData>,\n updater: Updater<ColumnFiltersState>,\n) {\n const leafColumnsById = table.getAllLeafColumnsById()\n\n const updateFn = (old: ColumnFiltersState) => {\n return functionalUpdate(updater, old).filter((filter) => {\n const column = leafColumnsById[filter.id]\n\n if (column) {\n const filterFn = column_getFilterFn(column)\n\n if (shouldAutoRemoveFilter(filterFn, filter.value, column)) {\n return false\n }\n }\n\n return true\n })\n }\n\n table.options.onColumnFiltersChange?.(updateFn)\n}\n\n/**\n * Resets `columnFilters` to the configured initial state or feature default.\n *\n * With no argument, the reset clones `table.initialState.columnFilters` when it\n * exists. Passing `true` ignores initial state and resets to `[]`.\n *\n * @example\n * ```ts\n * table_resetColumnFilters(table)\n * table_resetColumnFilters(table, true)\n * ```\n */\nexport function table_resetColumnFilters<\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(table: Table_Internal<TFeatures, TData>, defaultState?: boolean) {\n table_setColumnFilters(\n table,\n defaultState ? [] : cloneState(table.initialState.columnFilters ?? []),\n )\n}\n\n/**\n * Returns whether a filter value should be removed from filter state.\n *\n * This checks the filter function's `autoRemove` hook and built-in empty-value rules.\n *\n * @example\n * ```ts\n * const removeFilter = shouldAutoRemoveFilter(filterFn, value, column)\n * ```\n */\nexport function shouldAutoRemoveFilter<\n TFeatures extends TableFeatures,\n TData extends RowData,\n TValue extends CellData = CellData,\n>(\n filterFn?: FilterFn<TFeatures, TData>,\n value?: any,\n column?: Column_Internal<TFeatures, TData, TValue>,\n) {\n return (\n (filterFn && filterFn.autoRemove\n ? filterFn.autoRemove(value, column as any)\n : false) ||\n typeof value === 'undefined' ||\n (typeof value === 'string' && !value)\n )\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"columnFilteringFeature.utils.js","names":[],"sources":["../../../src/features/column-filtering/columnFilteringFeature.utils.ts"],"sourcesContent":["import { cloneState, functionalUpdate, isFunction } from '../../utils'\nimport type { CellData, RowData, Updater } from '../../types/type-utils'\nimport type { TableFeatures } from '../../types/TableFeatures'\nimport type { Table_Internal } from '../../types/Table'\nimport type { Column_Internal } from '../../types/Column'\nimport type {\n ColumnFiltersState,\n FilterFn,\n} from './columnFilteringFeature.types'\n\n/**\n * Creates the default column filter state.\n *\n * The feature default is an empty array, meaning no column filters are active.\n * Reset APIs use this value when `defaultState` is `true`.\n *\n * @example\n * ```ts\n * const filters = getDefaultColumnFiltersState()\n * ```\n */\nexport function getDefaultColumnFiltersState(): ColumnFiltersState {\n return []\n}\n\n/**\n * Chooses a built-in filter function from the column's first core row value.\n *\n * Strings use `includesString`, numbers use `inNumberRange`, booleans and\n * objects use `equals`, dates use `inDateRange`, arrays use `arrIncludes`,\n * and unknown values fall back to `weakEquals`.\n *\n * The chosen filter function is looked up in the table's `filterFns`\n * registry. When it is not registered there, this returns `undefined` and\n * warns in development instead of substituting a different filter function.\n *\n * @example\n * ```ts\n * const filterFn = column_getAutoFilterFn(column)\n * ```\n */\nexport function column_getAutoFilterFn<\n TFeatures extends TableFeatures,\n TData extends RowData,\n TValue extends CellData = CellData,\n>(column: Column_Internal<TFeatures, TData, TValue>) {\n const filterFns: Record<string, FilterFn<TFeatures, TData>> | undefined =\n column.table._rowModelFns.filterFns\n\n const firstRow = column.table.getCoreRowModel().flatRows[0]\n\n const value = firstRow ? firstRow.getValue(column.id) : undefined\n\n let filterFnName: string\n\n if (typeof value === 'string') {\n filterFnName = 'includesString'\n } else if (typeof value === 'number') {\n filterFnName = 'inNumberRange'\n } else if (typeof value === 'boolean') {\n filterFnName = 'equals'\n } else if (Array.isArray(value)) {\n filterFnName = 'arrIncludes'\n } else if (Object.prototype.toString.call(value) === '[object Date]') {\n filterFnName = 'inDateRange'\n } else if (value !== null && typeof value === 'object') {\n filterFnName = 'equals'\n } else {\n filterFnName = 'weakEquals'\n }\n\n const filterFn = filterFns?.[filterFnName]\n\n if (process.env.NODE_ENV === 'development' && !filterFn) {\n console.warn(\n `filterFn '${filterFnName}' (auto) for column '${column.id}' is not registered`,\n )\n }\n\n return filterFn\n}\n\n/**\n * Resolves the filter function configured for a column.\n *\n * Function-valued `columnDef.filterFn` is returned directly, `'auto'` delegates\n * to `column_getAutoFilterFn`, and string values are looked up in the table's\n * filter function registry.\n *\n * @example\n * ```ts\n * const filterFn = column_getFilterFn(column)\n * ```\n */\nexport function column_getFilterFn<\n TFeatures extends TableFeatures,\n TData extends RowData,\n TValue extends CellData = CellData,\n>(\n column: Column_Internal<TFeatures, TData, TValue>,\n): FilterFn<TFeatures, TData> | undefined {\n let filterFn = null\n const filterFns: Record<string, FilterFn<TFeatures, TData>> | undefined =\n column.table._rowModelFns.filterFns\n filterFn = isFunction(column.columnDef.filterFn)\n ? column.columnDef.filterFn\n : column.columnDef.filterFn === 'auto'\n ? column_getAutoFilterFn(column)\n : filterFns?.[column.columnDef.filterFn as string]\n\n if (\n process.env.NODE_ENV === 'development' &&\n !filterFn &&\n column.columnDef.filterFn !== 'auto' // the auto picker warns on its own\n ) {\n console.warn(\n `filterFn '${String(column.columnDef.filterFn)}' for column '${column.id}' is not registered`,\n )\n }\n\n return filterFn ?? undefined\n}\n\n/**\n * Checks whether column filtering is enabled for this accessor column.\n *\n * The column must have an accessor and filtering must be enabled by the column\n * definition, `enableColumnFilters`, and the table-wide `enableFilters` option.\n *\n * @example\n * ```ts\n * const canFilter = column_getCanFilter(column)\n * ```\n */\nexport function column_getCanFilter<\n TFeatures extends TableFeatures,\n TData extends RowData,\n TValue extends CellData = CellData,\n>(column: Column_Internal<TFeatures, TData, TValue>) {\n return (\n (column.columnDef.enableColumnFilter ?? true) &&\n (column.table.options.enableColumnFilters ?? true) &&\n (column.table.options.enableFilters ?? true) &&\n !!column.accessorFn\n )\n}\n\n/**\n * Checks whether this column currently has an entry in `state.columnFilters`.\n *\n * This only reflects filter state presence; it does not indicate whether the\n * filter removes any rows.\n *\n * @example\n * ```ts\n * const isFiltered = column_getIsFiltered(column)\n * ```\n */\nexport function column_getIsFiltered<\n TFeatures extends TableFeatures,\n TData extends RowData,\n TValue extends CellData = CellData,\n>(column: Column_Internal<TFeatures, TData, TValue>) {\n return column_getFilterIndex(column) > -1\n}\n\n/**\n * Reads this column's current filter value from `state.columnFilters`.\n *\n * Missing filter entries return `undefined`.\n *\n * @example\n * ```ts\n * const value = column_getFilterValue(column)\n * ```\n */\nexport function column_getFilterValue<\n TFeatures extends TableFeatures,\n TData extends RowData,\n TValue extends CellData = CellData,\n>(column: Column_Internal<TFeatures, TData, TValue>) {\n return column.table.atoms.columnFilters\n ?.get()\n ?.find((d) => d.id === column.id)?.value\n}\n\n/**\n * Finds this column's position in the ordered `state.columnFilters` array.\n *\n * The result is `-1` when the column has no active filter.\n *\n * @example\n * ```ts\n * const index = column_getFilterIndex(column)\n * ```\n */\nexport function column_getFilterIndex<\n TFeatures extends TableFeatures,\n TData extends RowData,\n TValue extends CellData = CellData,\n>(column: Column_Internal<TFeatures, TData, TValue>): number {\n return (\n column.table.atoms.columnFilters\n ?.get()\n ?.findIndex((d) => d.id === column.id) ?? -1\n )\n}\n\n/**\n * Adds, updates, or removes this column's filter value.\n *\n * The incoming value may be an updater. After resolution, `autoRemove` rules\n * decide whether the filter should be removed instead of stored.\n *\n * @example\n * ```ts\n * column_setFilterValue(column, (old) => String(old ?? '').trim())\n * ```\n */\nexport function column_setFilterValue<\n TFeatures extends TableFeatures,\n TData extends RowData,\n TValue extends CellData = CellData,\n>(column: Column_Internal<TFeatures, TData, TValue>, value: any) {\n table_setColumnFilters(column.table, (old) => {\n const filterFn = column_getFilterFn(column)\n const previousFilter = old.find((d) => d.id === column.id)\n\n const newFilter = functionalUpdate(\n value,\n previousFilter ? previousFilter.value : undefined,\n )\n\n if (shouldAutoRemoveFilter(filterFn, newFilter, column)) {\n return old.filter((d) => d.id !== column.id)\n }\n\n const newFilterObj = { id: column.id, value: newFilter }\n\n if (previousFilter) {\n return old.map((d) => {\n if (d.id === column.id) {\n return newFilterObj\n }\n return d\n })\n }\n\n if (old.length) {\n return [...old, newFilterObj]\n }\n\n return [newFilterObj]\n })\n}\n\n/**\n * Routes a column filter updater through the table's filter change handler.\n *\n * The resolved filters are cleaned before they are emitted: filters for known\n * columns are removed when their filter function says the value should be\n * auto-removed.\n *\n * @example\n * ```ts\n * table_setColumnFilters(table, (old) => old.filter((filter) => filter.id !== 'age'))\n * ```\n */\nexport function table_setColumnFilters<\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(\n table: Table_Internal<TFeatures, TData>,\n updater: Updater<ColumnFiltersState>,\n) {\n const leafColumnsById = table.getAllLeafColumnsById()\n\n const updateFn = (old: ColumnFiltersState) => {\n return functionalUpdate(updater, old).filter((filter) => {\n const column = leafColumnsById[filter.id]\n\n if (column) {\n const filterFn = column_getFilterFn(column)\n\n if (shouldAutoRemoveFilter(filterFn, filter.value, column)) {\n return false\n }\n }\n\n return true\n })\n }\n\n table.options.onColumnFiltersChange?.(updateFn)\n}\n\n/**\n * Resets `columnFilters` to the configured initial state or feature default.\n *\n * With no argument, the reset clones `table.initialState.columnFilters` when it\n * exists. Passing `true` ignores initial state and resets to `[]`.\n *\n * @example\n * ```ts\n * table_resetColumnFilters(table)\n * table_resetColumnFilters(table, true)\n * ```\n */\nexport function table_resetColumnFilters<\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(table: Table_Internal<TFeatures, TData>, defaultState?: boolean) {\n table_setColumnFilters(\n table,\n defaultState ? [] : cloneState(table.initialState.columnFilters ?? []),\n )\n}\n\n/**\n * Returns whether a filter value should be removed from filter state.\n *\n * This checks the filter function's `autoRemove` hook and built-in empty-value rules.\n *\n * @example\n * ```ts\n * const removeFilter = shouldAutoRemoveFilter(filterFn, value, column)\n * ```\n */\nexport function shouldAutoRemoveFilter<\n TFeatures extends TableFeatures,\n TData extends RowData,\n TValue extends CellData = CellData,\n>(\n filterFn?: FilterFn<TFeatures, TData>,\n value?: any,\n column?: Column_Internal<TFeatures, TData, TValue>,\n) {\n return (\n (filterFn && filterFn.autoRemove\n ? filterFn.autoRemove(value, column as any)\n : false) ||\n typeof value === 'undefined' ||\n (typeof value === 'string' && !value)\n )\n}\n"],"mappings":"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"}
@@ -11,8 +11,12 @@ const require_filterRowsUtils = require('./filterRowsUtils.cjs');
11
11
  *
12
12
  * The factory reads the relevant table state atoms and options, then returns a row model function used by the table row-model pipeline.
13
13
  *
14
- * Register filter functions with the `filterFns` slot on the `features` option:
15
- * `tableFeatures({ columnFilteringFeature, filteredRowModel: createFilteredRowModel(), filterFns })`.
14
+ * Register the filter functions you use with the `filterFns` slot on the
15
+ * `features` option:
16
+ * `tableFeatures({ columnFilteringFeature, filteredRowModel: createFilteredRowModel(), filterFns: { includesString: filterFn_includesString } })`.
17
+ * Importing individual `filterFn_*` functions keeps unused built-ins out of
18
+ * your bundle; filter functions passed directly to the `filterFn` column
19
+ * option need no registration at all.
16
20
  */
17
21
  function createFilteredRowModel() {
18
22
  return (_table) => {
@@ -50,6 +54,7 @@ function _createFilteredRowModel(table) {
50
54
  const column = require_coreColumnsFeature_utils.table_getColumn(table, columnFilter.id);
51
55
  if (!column) return;
52
56
  const filterFn = require_columnFilteringFeature_utils.column_getFilterFn(column);
57
+ if (!filterFn) return;
53
58
  resolvedColumnFilters.push({
54
59
  id: columnFilter.id,
55
60
  filterFn,
@@ -1 +1 @@
1
- {"version":3,"file":"createFilteredRowModel.cjs","names":["tableMemo","table_autoResetPageIndex","makeObjectMap","table_getColumn","column_getFilterFn","table_getGlobalFilterFn","column_getCanGlobalFilter","filterRows"],"sources":["../../../src/features/column-filtering/createFilteredRowModel.ts"],"sourcesContent":["import { makeObjectMap, tableMemo } from '../../utils'\nimport { table_getColumn } from '../../core/columns/coreColumnsFeature.utils'\nimport {\n column_getCanGlobalFilter,\n table_getGlobalFilterFn,\n} from '../global-filtering/globalFilteringFeature.utils'\nimport { table_autoResetPageIndex } from '../row-pagination/rowPaginationFeature.utils'\nimport { filterRows } from './filterRowsUtils'\nimport { column_getFilterFn } from './columnFilteringFeature.utils'\nimport type { RowData } from '../../types/type-utils'\nimport type { TableFeatures } from '../../types/TableFeatures'\nimport type { RowModel } from '../../core/row-models/coreRowModelsFeature.types'\nimport type { Table, Table_Internal } from '../../types/Table'\nimport type { Row } from '../../types/Row'\nimport type {\n ResolvedColumnFilter,\n Row_ColumnFiltering,\n} from './columnFilteringFeature.types'\n\n/**\n * Creates a memoized filtered row model factory.\n *\n * The factory reads the relevant table state atoms and options, then returns a row model function used by the table row-model pipeline.\n *\n * Register filter functions with the `filterFns` slot on the `features` option:\n * `tableFeatures({ columnFilteringFeature, filteredRowModel: createFilteredRowModel(), filterFns })`.\n */\nexport function createFilteredRowModel<\n TFeatures extends TableFeatures,\n TData extends RowData = any,\n>(): (table: Table<TFeatures, TData>) => () => RowModel<TFeatures, TData> {\n return (_table) => {\n const table = _table as unknown as Table_Internal<TFeatures, TData>\n return tableMemo({\n feature: 'columnFilteringFeature',\n table,\n fnName: 'table.getFilteredRowModel',\n memoDeps: () => [\n table.getPreFilteredRowModel(),\n table.atoms.columnFilters?.get(),\n table.atoms.globalFilter?.get(),\n ],\n fn: () => _createFilteredRowModel(table),\n onAfterUpdate: () => table_autoResetPageIndex(table),\n })\n }\n}\n\nfunction _createFilteredRowModel<\n TFeatures extends TableFeatures,\n TData extends RowData = any,\n>(table: Table_Internal<TFeatures, TData>): RowModel<TFeatures, TData> {\n const rowModel = table.getPreFilteredRowModel()\n const columnFilters = table.atoms.columnFilters?.get()\n const globalFilter = table.atoms.globalFilter?.get()\n\n if (!rowModel.rows.length || (!columnFilters?.length && !globalFilter)) {\n const flatRows = rowModel.flatRows as Array<\n Row<TFeatures, TData> & Partial<Row_ColumnFiltering<TFeatures, TData>>\n >\n for (let i = 0; i < flatRows.length; i++) {\n const row = flatRows[i]!\n row.columnFilters = makeObjectMap()\n row.columnFiltersMeta = makeObjectMap()\n }\n return rowModel\n }\n\n const resolvedColumnFilters: Array<ResolvedColumnFilter<TFeatures, TData>> =\n []\n const resolvedGlobalFilters: Array<ResolvedColumnFilter<TFeatures, TData>> =\n []\n\n columnFilters?.forEach((columnFilter) => {\n const column = table_getColumn(table, columnFilter.id)\n\n if (!column) {\n return\n }\n\n const filterFn = column_getFilterFn(column)!\n\n resolvedColumnFilters.push({\n id: columnFilter.id,\n filterFn,\n resolvedValue:\n filterFn.resolveFilterValue?.(columnFilter.value) ?? columnFilter.value,\n })\n })\n\n const filterableIds = columnFilters?.map((d) => d.id) ?? []\n\n const globalFilterFn = table_getGlobalFilterFn(table)\n\n const globallyFilterableColumns = table\n .getAllLeafColumns()\n .filter((column) => column_getCanGlobalFilter(column))\n\n if (globalFilter && globalFilterFn && globallyFilterableColumns.length) {\n filterableIds.push('__global__')\n\n globallyFilterableColumns.forEach((column) => {\n resolvedGlobalFilters.push({\n id: column.id,\n filterFn: globalFilterFn,\n resolvedValue:\n globalFilterFn.resolveFilterValue?.(globalFilter) ?? globalFilter,\n })\n })\n }\n\n // Flag the pre-filtered row model with each filter state\n const flatRows = rowModel.flatRows as Array<\n Row<TFeatures, TData> & Partial<Row_ColumnFiltering<TFeatures, TData>>\n >\n for (let i = 0; i < flatRows.length; i++) {\n const row = flatRows[i]!\n row.columnFilters = makeObjectMap()\n row.columnFiltersMeta = makeObjectMap()\n\n if (resolvedColumnFilters.length) {\n for (let j = 0; j < resolvedColumnFilters.length; j++) {\n const currentColumnFilter = resolvedColumnFilters[j]!\n const id = currentColumnFilter.id\n\n // Tag the row with the column filter state\n row.columnFilters[id] = currentColumnFilter.filterFn(\n row,\n id,\n currentColumnFilter.resolvedValue,\n (filterMeta) => {\n if (!row.columnFiltersMeta) {\n row.columnFiltersMeta = makeObjectMap()\n }\n row.columnFiltersMeta[id] = filterMeta\n },\n )\n }\n }\n\n if (resolvedGlobalFilters.length) {\n for (let j = 0; j < resolvedGlobalFilters.length; j++) {\n const currentGlobalFilter = resolvedGlobalFilters[j]!\n const id = currentGlobalFilter.id\n // Tag the row with the first truthy global filter state\n if (\n currentGlobalFilter.filterFn(\n row,\n id,\n currentGlobalFilter.resolvedValue,\n (filterMeta) => {\n if (!row.columnFiltersMeta) {\n row.columnFiltersMeta = makeObjectMap()\n }\n row.columnFiltersMeta[id] = filterMeta\n },\n )\n ) {\n row.columnFilters.__global__ = true\n break\n }\n }\n\n if (row.columnFilters.__global__ !== true) {\n row.columnFilters.__global__ = false\n }\n }\n }\n\n const filterRowsImpl = (\n row: Row<TFeatures, TData> & Row_ColumnFiltering<TFeatures, TData>,\n ) => {\n // Horizontally filter rows through each column\n for (let i = 0; i < filterableIds.length; i++) {\n if (row.columnFilters[filterableIds[i]!] === false) {\n return false\n }\n }\n return true\n }\n\n // Filter final rows using all of the active filters\n return filterRows(rowModel.rows, filterRowsImpl as any, table)\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"createFilteredRowModel.cjs","names":["tableMemo","table_autoResetPageIndex","makeObjectMap","table_getColumn","column_getFilterFn","table_getGlobalFilterFn","column_getCanGlobalFilter","filterRows"],"sources":["../../../src/features/column-filtering/createFilteredRowModel.ts"],"sourcesContent":["import { makeObjectMap, tableMemo } from '../../utils'\nimport { table_getColumn } from '../../core/columns/coreColumnsFeature.utils'\nimport {\n column_getCanGlobalFilter,\n table_getGlobalFilterFn,\n} from '../global-filtering/globalFilteringFeature.utils'\nimport { table_autoResetPageIndex } from '../row-pagination/rowPaginationFeature.utils'\nimport { filterRows } from './filterRowsUtils'\nimport { column_getFilterFn } from './columnFilteringFeature.utils'\nimport type { RowData } from '../../types/type-utils'\nimport type { TableFeatures } from '../../types/TableFeatures'\nimport type { RowModel } from '../../core/row-models/coreRowModelsFeature.types'\nimport type { Table, Table_Internal } from '../../types/Table'\nimport type { Row } from '../../types/Row'\nimport type {\n ResolvedColumnFilter,\n Row_ColumnFiltering,\n} from './columnFilteringFeature.types'\n\n/**\n * Creates a memoized filtered row model factory.\n *\n * The factory reads the relevant table state atoms and options, then returns a row model function used by the table row-model pipeline.\n *\n * Register the filter functions you use with the `filterFns` slot on the\n * `features` option:\n * `tableFeatures({ columnFilteringFeature, filteredRowModel: createFilteredRowModel(), filterFns: { includesString: filterFn_includesString } })`.\n * Importing individual `filterFn_*` functions keeps unused built-ins out of\n * your bundle; filter functions passed directly to the `filterFn` column\n * option need no registration at all.\n */\nexport function createFilteredRowModel<\n TFeatures extends TableFeatures,\n TData extends RowData = any,\n>(): (table: Table<TFeatures, TData>) => () => RowModel<TFeatures, TData> {\n return (_table) => {\n const table = _table as unknown as Table_Internal<TFeatures, TData>\n return tableMemo({\n feature: 'columnFilteringFeature',\n table,\n fnName: 'table.getFilteredRowModel',\n memoDeps: () => [\n table.getPreFilteredRowModel(),\n table.atoms.columnFilters?.get(),\n table.atoms.globalFilter?.get(),\n ],\n fn: () => _createFilteredRowModel(table),\n onAfterUpdate: () => table_autoResetPageIndex(table),\n })\n }\n}\n\nfunction _createFilteredRowModel<\n TFeatures extends TableFeatures,\n TData extends RowData = any,\n>(table: Table_Internal<TFeatures, TData>): RowModel<TFeatures, TData> {\n const rowModel = table.getPreFilteredRowModel()\n const columnFilters = table.atoms.columnFilters?.get()\n const globalFilter = table.atoms.globalFilter?.get()\n\n if (!rowModel.rows.length || (!columnFilters?.length && !globalFilter)) {\n const flatRows = rowModel.flatRows as Array<\n Row<TFeatures, TData> & Partial<Row_ColumnFiltering<TFeatures, TData>>\n >\n for (let i = 0; i < flatRows.length; i++) {\n const row = flatRows[i]!\n row.columnFilters = makeObjectMap()\n row.columnFiltersMeta = makeObjectMap()\n }\n return rowModel\n }\n\n const resolvedColumnFilters: Array<ResolvedColumnFilter<TFeatures, TData>> =\n []\n const resolvedGlobalFilters: Array<ResolvedColumnFilter<TFeatures, TData>> =\n []\n\n columnFilters?.forEach((columnFilter) => {\n const column = table_getColumn(table, columnFilter.id)\n\n if (!column) {\n return\n }\n\n const filterFn = column_getFilterFn(column)\n\n // A dev warning has already fired in column_getFilterFn; ignore the\n // filter instead of crashing when its filter fn is not registered.\n if (!filterFn) {\n return\n }\n\n resolvedColumnFilters.push({\n id: columnFilter.id,\n filterFn,\n resolvedValue:\n filterFn.resolveFilterValue?.(columnFilter.value) ?? columnFilter.value,\n })\n })\n\n const filterableIds = columnFilters?.map((d) => d.id) ?? []\n\n const globalFilterFn = table_getGlobalFilterFn(table)\n\n const globallyFilterableColumns = table\n .getAllLeafColumns()\n .filter((column) => column_getCanGlobalFilter(column))\n\n if (globalFilter && globalFilterFn && globallyFilterableColumns.length) {\n filterableIds.push('__global__')\n\n globallyFilterableColumns.forEach((column) => {\n resolvedGlobalFilters.push({\n id: column.id,\n filterFn: globalFilterFn,\n resolvedValue:\n globalFilterFn.resolveFilterValue?.(globalFilter) ?? globalFilter,\n })\n })\n }\n\n // Flag the pre-filtered row model with each filter state\n const flatRows = rowModel.flatRows as Array<\n Row<TFeatures, TData> & Partial<Row_ColumnFiltering<TFeatures, TData>>\n >\n for (let i = 0; i < flatRows.length; i++) {\n const row = flatRows[i]!\n row.columnFilters = makeObjectMap()\n row.columnFiltersMeta = makeObjectMap()\n\n if (resolvedColumnFilters.length) {\n for (let j = 0; j < resolvedColumnFilters.length; j++) {\n const currentColumnFilter = resolvedColumnFilters[j]!\n const id = currentColumnFilter.id\n\n // Tag the row with the column filter state\n row.columnFilters[id] = currentColumnFilter.filterFn(\n row,\n id,\n currentColumnFilter.resolvedValue,\n (filterMeta) => {\n if (!row.columnFiltersMeta) {\n row.columnFiltersMeta = makeObjectMap()\n }\n row.columnFiltersMeta[id] = filterMeta\n },\n )\n }\n }\n\n if (resolvedGlobalFilters.length) {\n for (let j = 0; j < resolvedGlobalFilters.length; j++) {\n const currentGlobalFilter = resolvedGlobalFilters[j]!\n const id = currentGlobalFilter.id\n // Tag the row with the first truthy global filter state\n if (\n currentGlobalFilter.filterFn(\n row,\n id,\n currentGlobalFilter.resolvedValue,\n (filterMeta) => {\n if (!row.columnFiltersMeta) {\n row.columnFiltersMeta = makeObjectMap()\n }\n row.columnFiltersMeta[id] = filterMeta\n },\n )\n ) {\n row.columnFilters.__global__ = true\n break\n }\n }\n\n if (row.columnFilters.__global__ !== true) {\n row.columnFilters.__global__ = false\n }\n }\n }\n\n const filterRowsImpl = (\n row: Row<TFeatures, TData> & Row_ColumnFiltering<TFeatures, TData>,\n ) => {\n // Horizontally filter rows through each column\n for (let i = 0; i < filterableIds.length; i++) {\n if (row.columnFilters[filterableIds[i]!] === false) {\n return false\n }\n }\n return true\n }\n\n // Filter final rows using all of the active filters\n return filterRows(rowModel.rows, filterRowsImpl as any, table)\n}\n"],"mappings":"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"}
@@ -9,8 +9,12 @@ import { TableFeatures } from "../../types/TableFeatures.cjs";
9
9
  *
10
10
  * The factory reads the relevant table state atoms and options, then returns a row model function used by the table row-model pipeline.
11
11
  *
12
- * Register filter functions with the `filterFns` slot on the `features` option:
13
- * `tableFeatures({ columnFilteringFeature, filteredRowModel: createFilteredRowModel(), filterFns })`.
12
+ * Register the filter functions you use with the `filterFns` slot on the
13
+ * `features` option:
14
+ * `tableFeatures({ columnFilteringFeature, filteredRowModel: createFilteredRowModel(), filterFns: { includesString: filterFn_includesString } })`.
15
+ * Importing individual `filterFn_*` functions keeps unused built-ins out of
16
+ * your bundle; filter functions passed directly to the `filterFn` column
17
+ * option need no registration at all.
14
18
  */
15
19
  declare function createFilteredRowModel<TFeatures extends TableFeatures, TData extends RowData = any>(): (table: Table<TFeatures, TData>) => () => RowModel<TFeatures, TData>;
16
20
  //#endregion
@@ -9,8 +9,12 @@ import { TableFeatures } from "../../types/TableFeatures.js";
9
9
  *
10
10
  * The factory reads the relevant table state atoms and options, then returns a row model function used by the table row-model pipeline.
11
11
  *
12
- * Register filter functions with the `filterFns` slot on the `features` option:
13
- * `tableFeatures({ columnFilteringFeature, filteredRowModel: createFilteredRowModel(), filterFns })`.
12
+ * Register the filter functions you use with the `filterFns` slot on the
13
+ * `features` option:
14
+ * `tableFeatures({ columnFilteringFeature, filteredRowModel: createFilteredRowModel(), filterFns: { includesString: filterFn_includesString } })`.
15
+ * Importing individual `filterFn_*` functions keeps unused built-ins out of
16
+ * your bundle; filter functions passed directly to the `filterFn` column
17
+ * option need no registration at all.
14
18
  */
15
19
  declare function createFilteredRowModel<TFeatures extends TableFeatures, TData extends RowData = any>(): (table: Table<TFeatures, TData>) => () => RowModel<TFeatures, TData>;
16
20
  //#endregion
@@ -11,8 +11,12 @@ import { filterRows } from "./filterRowsUtils.js";
11
11
  *
12
12
  * The factory reads the relevant table state atoms and options, then returns a row model function used by the table row-model pipeline.
13
13
  *
14
- * Register filter functions with the `filterFns` slot on the `features` option:
15
- * `tableFeatures({ columnFilteringFeature, filteredRowModel: createFilteredRowModel(), filterFns })`.
14
+ * Register the filter functions you use with the `filterFns` slot on the
15
+ * `features` option:
16
+ * `tableFeatures({ columnFilteringFeature, filteredRowModel: createFilteredRowModel(), filterFns: { includesString: filterFn_includesString } })`.
17
+ * Importing individual `filterFn_*` functions keeps unused built-ins out of
18
+ * your bundle; filter functions passed directly to the `filterFn` column
19
+ * option need no registration at all.
16
20
  */
17
21
  function createFilteredRowModel() {
18
22
  return (_table) => {
@@ -50,6 +54,7 @@ function _createFilteredRowModel(table) {
50
54
  const column = table_getColumn(table, columnFilter.id);
51
55
  if (!column) return;
52
56
  const filterFn = column_getFilterFn(column);
57
+ if (!filterFn) return;
53
58
  resolvedColumnFilters.push({
54
59
  id: columnFilter.id,
55
60
  filterFn,
@@ -1 +1 @@
1
- {"version":3,"file":"createFilteredRowModel.js","names":[],"sources":["../../../src/features/column-filtering/createFilteredRowModel.ts"],"sourcesContent":["import { makeObjectMap, tableMemo } from '../../utils'\nimport { table_getColumn } from '../../core/columns/coreColumnsFeature.utils'\nimport {\n column_getCanGlobalFilter,\n table_getGlobalFilterFn,\n} from '../global-filtering/globalFilteringFeature.utils'\nimport { table_autoResetPageIndex } from '../row-pagination/rowPaginationFeature.utils'\nimport { filterRows } from './filterRowsUtils'\nimport { column_getFilterFn } from './columnFilteringFeature.utils'\nimport type { RowData } from '../../types/type-utils'\nimport type { TableFeatures } from '../../types/TableFeatures'\nimport type { RowModel } from '../../core/row-models/coreRowModelsFeature.types'\nimport type { Table, Table_Internal } from '../../types/Table'\nimport type { Row } from '../../types/Row'\nimport type {\n ResolvedColumnFilter,\n Row_ColumnFiltering,\n} from './columnFilteringFeature.types'\n\n/**\n * Creates a memoized filtered row model factory.\n *\n * The factory reads the relevant table state atoms and options, then returns a row model function used by the table row-model pipeline.\n *\n * Register filter functions with the `filterFns` slot on the `features` option:\n * `tableFeatures({ columnFilteringFeature, filteredRowModel: createFilteredRowModel(), filterFns })`.\n */\nexport function createFilteredRowModel<\n TFeatures extends TableFeatures,\n TData extends RowData = any,\n>(): (table: Table<TFeatures, TData>) => () => RowModel<TFeatures, TData> {\n return (_table) => {\n const table = _table as unknown as Table_Internal<TFeatures, TData>\n return tableMemo({\n feature: 'columnFilteringFeature',\n table,\n fnName: 'table.getFilteredRowModel',\n memoDeps: () => [\n table.getPreFilteredRowModel(),\n table.atoms.columnFilters?.get(),\n table.atoms.globalFilter?.get(),\n ],\n fn: () => _createFilteredRowModel(table),\n onAfterUpdate: () => table_autoResetPageIndex(table),\n })\n }\n}\n\nfunction _createFilteredRowModel<\n TFeatures extends TableFeatures,\n TData extends RowData = any,\n>(table: Table_Internal<TFeatures, TData>): RowModel<TFeatures, TData> {\n const rowModel = table.getPreFilteredRowModel()\n const columnFilters = table.atoms.columnFilters?.get()\n const globalFilter = table.atoms.globalFilter?.get()\n\n if (!rowModel.rows.length || (!columnFilters?.length && !globalFilter)) {\n const flatRows = rowModel.flatRows as Array<\n Row<TFeatures, TData> & Partial<Row_ColumnFiltering<TFeatures, TData>>\n >\n for (let i = 0; i < flatRows.length; i++) {\n const row = flatRows[i]!\n row.columnFilters = makeObjectMap()\n row.columnFiltersMeta = makeObjectMap()\n }\n return rowModel\n }\n\n const resolvedColumnFilters: Array<ResolvedColumnFilter<TFeatures, TData>> =\n []\n const resolvedGlobalFilters: Array<ResolvedColumnFilter<TFeatures, TData>> =\n []\n\n columnFilters?.forEach((columnFilter) => {\n const column = table_getColumn(table, columnFilter.id)\n\n if (!column) {\n return\n }\n\n const filterFn = column_getFilterFn(column)!\n\n resolvedColumnFilters.push({\n id: columnFilter.id,\n filterFn,\n resolvedValue:\n filterFn.resolveFilterValue?.(columnFilter.value) ?? columnFilter.value,\n })\n })\n\n const filterableIds = columnFilters?.map((d) => d.id) ?? []\n\n const globalFilterFn = table_getGlobalFilterFn(table)\n\n const globallyFilterableColumns = table\n .getAllLeafColumns()\n .filter((column) => column_getCanGlobalFilter(column))\n\n if (globalFilter && globalFilterFn && globallyFilterableColumns.length) {\n filterableIds.push('__global__')\n\n globallyFilterableColumns.forEach((column) => {\n resolvedGlobalFilters.push({\n id: column.id,\n filterFn: globalFilterFn,\n resolvedValue:\n globalFilterFn.resolveFilterValue?.(globalFilter) ?? globalFilter,\n })\n })\n }\n\n // Flag the pre-filtered row model with each filter state\n const flatRows = rowModel.flatRows as Array<\n Row<TFeatures, TData> & Partial<Row_ColumnFiltering<TFeatures, TData>>\n >\n for (let i = 0; i < flatRows.length; i++) {\n const row = flatRows[i]!\n row.columnFilters = makeObjectMap()\n row.columnFiltersMeta = makeObjectMap()\n\n if (resolvedColumnFilters.length) {\n for (let j = 0; j < resolvedColumnFilters.length; j++) {\n const currentColumnFilter = resolvedColumnFilters[j]!\n const id = currentColumnFilter.id\n\n // Tag the row with the column filter state\n row.columnFilters[id] = currentColumnFilter.filterFn(\n row,\n id,\n currentColumnFilter.resolvedValue,\n (filterMeta) => {\n if (!row.columnFiltersMeta) {\n row.columnFiltersMeta = makeObjectMap()\n }\n row.columnFiltersMeta[id] = filterMeta\n },\n )\n }\n }\n\n if (resolvedGlobalFilters.length) {\n for (let j = 0; j < resolvedGlobalFilters.length; j++) {\n const currentGlobalFilter = resolvedGlobalFilters[j]!\n const id = currentGlobalFilter.id\n // Tag the row with the first truthy global filter state\n if (\n currentGlobalFilter.filterFn(\n row,\n id,\n currentGlobalFilter.resolvedValue,\n (filterMeta) => {\n if (!row.columnFiltersMeta) {\n row.columnFiltersMeta = makeObjectMap()\n }\n row.columnFiltersMeta[id] = filterMeta\n },\n )\n ) {\n row.columnFilters.__global__ = true\n break\n }\n }\n\n if (row.columnFilters.__global__ !== true) {\n row.columnFilters.__global__ = false\n }\n }\n }\n\n const filterRowsImpl = (\n row: Row<TFeatures, TData> & Row_ColumnFiltering<TFeatures, TData>,\n ) => {\n // Horizontally filter rows through each column\n for (let i = 0; i < filterableIds.length; i++) {\n if (row.columnFilters[filterableIds[i]!] === false) {\n return false\n }\n }\n return true\n }\n\n // Filter final rows using all of the active filters\n return filterRows(rowModel.rows, filterRowsImpl as any, table)\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"createFilteredRowModel.js","names":[],"sources":["../../../src/features/column-filtering/createFilteredRowModel.ts"],"sourcesContent":["import { makeObjectMap, tableMemo } from '../../utils'\nimport { table_getColumn } from '../../core/columns/coreColumnsFeature.utils'\nimport {\n column_getCanGlobalFilter,\n table_getGlobalFilterFn,\n} from '../global-filtering/globalFilteringFeature.utils'\nimport { table_autoResetPageIndex } from '../row-pagination/rowPaginationFeature.utils'\nimport { filterRows } from './filterRowsUtils'\nimport { column_getFilterFn } from './columnFilteringFeature.utils'\nimport type { RowData } from '../../types/type-utils'\nimport type { TableFeatures } from '../../types/TableFeatures'\nimport type { RowModel } from '../../core/row-models/coreRowModelsFeature.types'\nimport type { Table, Table_Internal } from '../../types/Table'\nimport type { Row } from '../../types/Row'\nimport type {\n ResolvedColumnFilter,\n Row_ColumnFiltering,\n} from './columnFilteringFeature.types'\n\n/**\n * Creates a memoized filtered row model factory.\n *\n * The factory reads the relevant table state atoms and options, then returns a row model function used by the table row-model pipeline.\n *\n * Register the filter functions you use with the `filterFns` slot on the\n * `features` option:\n * `tableFeatures({ columnFilteringFeature, filteredRowModel: createFilteredRowModel(), filterFns: { includesString: filterFn_includesString } })`.\n * Importing individual `filterFn_*` functions keeps unused built-ins out of\n * your bundle; filter functions passed directly to the `filterFn` column\n * option need no registration at all.\n */\nexport function createFilteredRowModel<\n TFeatures extends TableFeatures,\n TData extends RowData = any,\n>(): (table: Table<TFeatures, TData>) => () => RowModel<TFeatures, TData> {\n return (_table) => {\n const table = _table as unknown as Table_Internal<TFeatures, TData>\n return tableMemo({\n feature: 'columnFilteringFeature',\n table,\n fnName: 'table.getFilteredRowModel',\n memoDeps: () => [\n table.getPreFilteredRowModel(),\n table.atoms.columnFilters?.get(),\n table.atoms.globalFilter?.get(),\n ],\n fn: () => _createFilteredRowModel(table),\n onAfterUpdate: () => table_autoResetPageIndex(table),\n })\n }\n}\n\nfunction _createFilteredRowModel<\n TFeatures extends TableFeatures,\n TData extends RowData = any,\n>(table: Table_Internal<TFeatures, TData>): RowModel<TFeatures, TData> {\n const rowModel = table.getPreFilteredRowModel()\n const columnFilters = table.atoms.columnFilters?.get()\n const globalFilter = table.atoms.globalFilter?.get()\n\n if (!rowModel.rows.length || (!columnFilters?.length && !globalFilter)) {\n const flatRows = rowModel.flatRows as Array<\n Row<TFeatures, TData> & Partial<Row_ColumnFiltering<TFeatures, TData>>\n >\n for (let i = 0; i < flatRows.length; i++) {\n const row = flatRows[i]!\n row.columnFilters = makeObjectMap()\n row.columnFiltersMeta = makeObjectMap()\n }\n return rowModel\n }\n\n const resolvedColumnFilters: Array<ResolvedColumnFilter<TFeatures, TData>> =\n []\n const resolvedGlobalFilters: Array<ResolvedColumnFilter<TFeatures, TData>> =\n []\n\n columnFilters?.forEach((columnFilter) => {\n const column = table_getColumn(table, columnFilter.id)\n\n if (!column) {\n return\n }\n\n const filterFn = column_getFilterFn(column)\n\n // A dev warning has already fired in column_getFilterFn; ignore the\n // filter instead of crashing when its filter fn is not registered.\n if (!filterFn) {\n return\n }\n\n resolvedColumnFilters.push({\n id: columnFilter.id,\n filterFn,\n resolvedValue:\n filterFn.resolveFilterValue?.(columnFilter.value) ?? columnFilter.value,\n })\n })\n\n const filterableIds = columnFilters?.map((d) => d.id) ?? []\n\n const globalFilterFn = table_getGlobalFilterFn(table)\n\n const globallyFilterableColumns = table\n .getAllLeafColumns()\n .filter((column) => column_getCanGlobalFilter(column))\n\n if (globalFilter && globalFilterFn && globallyFilterableColumns.length) {\n filterableIds.push('__global__')\n\n globallyFilterableColumns.forEach((column) => {\n resolvedGlobalFilters.push({\n id: column.id,\n filterFn: globalFilterFn,\n resolvedValue:\n globalFilterFn.resolveFilterValue?.(globalFilter) ?? globalFilter,\n })\n })\n }\n\n // Flag the pre-filtered row model with each filter state\n const flatRows = rowModel.flatRows as Array<\n Row<TFeatures, TData> & Partial<Row_ColumnFiltering<TFeatures, TData>>\n >\n for (let i = 0; i < flatRows.length; i++) {\n const row = flatRows[i]!\n row.columnFilters = makeObjectMap()\n row.columnFiltersMeta = makeObjectMap()\n\n if (resolvedColumnFilters.length) {\n for (let j = 0; j < resolvedColumnFilters.length; j++) {\n const currentColumnFilter = resolvedColumnFilters[j]!\n const id = currentColumnFilter.id\n\n // Tag the row with the column filter state\n row.columnFilters[id] = currentColumnFilter.filterFn(\n row,\n id,\n currentColumnFilter.resolvedValue,\n (filterMeta) => {\n if (!row.columnFiltersMeta) {\n row.columnFiltersMeta = makeObjectMap()\n }\n row.columnFiltersMeta[id] = filterMeta\n },\n )\n }\n }\n\n if (resolvedGlobalFilters.length) {\n for (let j = 0; j < resolvedGlobalFilters.length; j++) {\n const currentGlobalFilter = resolvedGlobalFilters[j]!\n const id = currentGlobalFilter.id\n // Tag the row with the first truthy global filter state\n if (\n currentGlobalFilter.filterFn(\n row,\n id,\n currentGlobalFilter.resolvedValue,\n (filterMeta) => {\n if (!row.columnFiltersMeta) {\n row.columnFiltersMeta = makeObjectMap()\n }\n row.columnFiltersMeta[id] = filterMeta\n },\n )\n ) {\n row.columnFilters.__global__ = true\n break\n }\n }\n\n if (row.columnFilters.__global__ !== true) {\n row.columnFilters.__global__ = false\n }\n }\n }\n\n const filterRowsImpl = (\n row: Row<TFeatures, TData> & Row_ColumnFiltering<TFeatures, TData>,\n ) => {\n // Horizontally filter rows through each column\n for (let i = 0; i < filterableIds.length; i++) {\n if (row.columnFilters[filterableIds[i]!] === false) {\n return false\n }\n }\n return true\n }\n\n // Filter final rows using all of the active filters\n return filterRows(rowModel.rows, filterRowsImpl as any, table)\n}\n"],"mappings":"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"}
@@ -0,0 +1,399 @@
1
+
2
+ //#region src/features/column-filtering/filterFns.ts
3
+ /**
4
+ * Builds a `FilterFn` from a value-level comparator plus optional resolvers.
5
+ *
6
+ * The `filter` comparator receives the row's data value (already passed
7
+ * through `resolveDataValue` when one is defined) and the filter value
8
+ * (already passed through `resolveFilterValue` by the table). Keeping
9
+ * normalization in the resolvers means a variant of an existing filter
10
+ * function only has to swap the resolvers, not re-implement the comparison.
11
+ *
12
+ * The definition is attached to the returned function, so a variant can be
13
+ * created by spreading a built-in filter function and overriding what differs:
14
+ *
15
+ * ```ts
16
+ * const normalize = (value: unknown) =>
17
+ * String(value ?? '')
18
+ * .toLowerCase()
19
+ * .normalize('NFD')
20
+ * .replace(/\p{Diacritic}/gu, '')
21
+ *
22
+ * const includesStringIgnoreDiacritics = constructFilterFn({
23
+ * ...filterFn_includesString,
24
+ * resolveFilterValue: normalize,
25
+ * resolveDataValue: normalize,
26
+ * })
27
+ * ```
28
+ *
29
+ * Note: the table applies `resolveFilterValue` once per filter before any rows
30
+ * are tested. When calling a filter function directly (outside of a table),
31
+ * apply it yourself: `fn(row, columnId, fn.resolveFilterValue?.(value) ?? value)`.
32
+ */
33
+ function constructFilterFn(def) {
34
+ const filterFn = Object.assign((row, columnId, filterValue, addMeta) => {
35
+ const rawValue = row.getValue(columnId);
36
+ const dataValue = filterFn.resolveDataValue ? filterFn.resolveDataValue(rawValue) : rawValue;
37
+ return filterFn.filter(dataValue, filterValue, row, columnId, addMeta);
38
+ }, def);
39
+ return filterFn;
40
+ }
41
+ /**
42
+ * Keeps rows whose column value is strictly equal to the filter value.
43
+ *
44
+ * Uses JavaScript `===` comparison and auto-removes empty filter values.
45
+ */
46
+ const filterFn_equals = constructFilterFn({
47
+ filter: (dataValue, filterValue) => dataValue === filterValue,
48
+ autoRemove: (val) => testFalsy(val)
49
+ });
50
+ /**
51
+ * Keeps rows whose column value is loosely equal to the filter value.
52
+ *
53
+ * Uses JavaScript `==` comparison and auto-removes empty filter values. This is
54
+ * useful for matching string input against numeric row values.
55
+ */
56
+ const filterFn_weakEquals = constructFilterFn({
57
+ filter: (dataValue, filterValue) => dataValue == filterValue,
58
+ autoRemove: (val) => testFalsy(val)
59
+ });
60
+ /**
61
+ * Keeps rows whose stringified column value includes the filter text.
62
+ *
63
+ * Matching is case-sensitive and empty filter values are auto-removed.
64
+ */
65
+ const filterFn_includesStringSensitive = constructFilterFn({
66
+ filter: (dataValue, filterValue) => Boolean(dataValue?.includes(filterValue)),
67
+ autoRemove: (val) => testFalsy(val),
68
+ resolveFilterValue: (val) => String(val),
69
+ resolveDataValue: (val) => val == null ? void 0 : String(val)
70
+ });
71
+ /**
72
+ * Keeps rows whose stringified column value includes the filter text.
73
+ *
74
+ * Both values are lowercased before comparison, and empty filter values are
75
+ * auto-removed.
76
+ */
77
+ const filterFn_includesString = constructFilterFn({
78
+ filter: (dataValue, filterValue) => Boolean(dataValue?.includes(filterValue)),
79
+ autoRemove: (val) => testFalsy(val),
80
+ resolveFilterValue: (val) => String(val).toLowerCase(),
81
+ resolveDataValue: (val) => val == null ? void 0 : String(val).toLowerCase()
82
+ });
83
+ /**
84
+ * Keeps rows whose stringified column value equals the filter text.
85
+ *
86
+ * Both values are lowercased before comparison, and empty filter values are
87
+ * auto-removed.
88
+ */
89
+ const filterFn_equalsString = constructFilterFn({
90
+ filter: (dataValue, filterValue) => dataValue === filterValue,
91
+ autoRemove: (val) => testFalsy(val),
92
+ resolveFilterValue: (val) => String(val).toLowerCase(),
93
+ resolveDataValue: (val) => val == null ? void 0 : String(val).toLowerCase()
94
+ });
95
+ /**
96
+ * Keeps rows whose stringified column value exactly equals the filter text.
97
+ *
98
+ * Matching is case-sensitive and empty filter values are auto-removed.
99
+ */
100
+ const filterFn_equalsStringSensitive = constructFilterFn({
101
+ filter: (dataValue, filterValue) => dataValue === filterValue,
102
+ autoRemove: (val) => testFalsy(val),
103
+ resolveFilterValue: (val) => String(val),
104
+ resolveDataValue: (val) => val == null ? void 0 : String(val)
105
+ });
106
+ /**
107
+ * Keeps rows whose stringified column value starts with the filter text.
108
+ *
109
+ * Both values are lowercased before comparison, and empty filter values are
110
+ * auto-removed.
111
+ */
112
+ const filterFn_startsWith = constructFilterFn({
113
+ filter: (dataValue, filterValue) => Boolean(dataValue?.startsWith(filterValue)),
114
+ autoRemove: (val) => testFalsy(val),
115
+ resolveFilterValue: (val) => String(val).toLowerCase(),
116
+ resolveDataValue: (val) => val == null ? void 0 : String(val).toLowerCase()
117
+ });
118
+ /**
119
+ * Keeps rows whose stringified column value ends with the filter text.
120
+ *
121
+ * Both values are lowercased before comparison, and empty filter values are
122
+ * auto-removed.
123
+ */
124
+ const filterFn_endsWith = constructFilterFn({
125
+ filter: (dataValue, filterValue) => Boolean(dataValue?.endsWith(filterValue)),
126
+ autoRemove: (val) => testFalsy(val),
127
+ resolveFilterValue: (val) => String(val).toLowerCase(),
128
+ resolveDataValue: (val) => val == null ? void 0 : String(val).toLowerCase()
129
+ });
130
+ /**
131
+ * Keeps rows whose column value is empty.
132
+ *
133
+ * A value is empty when it is nullish or stringifies to whitespace only. The
134
+ * filter value acts as an on/off flag: `false` and blank values are
135
+ * auto-removed.
136
+ */
137
+ const filterFn_empty = constructFilterFn({
138
+ filter: (dataValue) => testValueEmpty(dataValue),
139
+ autoRemove: (val) => testFalsy(val) || val === false
140
+ });
141
+ /**
142
+ * Keeps rows whose column value is not empty.
143
+ *
144
+ * A value is empty when it is nullish or stringifies to whitespace only. The
145
+ * filter value acts as an on/off flag: `false` and blank values are
146
+ * auto-removed.
147
+ */
148
+ const filterFn_notEmpty = constructFilterFn({
149
+ filter: (dataValue) => !testValueEmpty(dataValue),
150
+ autoRemove: (val) => testFalsy(val) || val === false
151
+ });
152
+ /**
153
+ * Keeps rows whose value is greater than the filter value.
154
+ *
155
+ * Numeric values are compared numerically when both sides can be coerced to
156
+ * numbers; otherwise normalized strings are compared.
157
+ */
158
+ const filterFn_greaterThan = constructFilterFn({
159
+ filter: (dataValue, filterValue) => compareGreaterThan(dataValue, filterValue),
160
+ autoRemove: (val) => testFalsy(val)
161
+ });
162
+ /**
163
+ * Keeps rows whose value is greater than or equal to the filter value.
164
+ *
165
+ * Delegates to the built-in greater-than and strict-equality comparisons.
166
+ */
167
+ const filterFn_greaterThanOrEqualTo = constructFilterFn({
168
+ filter: (dataValue, filterValue) => compareGreaterThanOrEqualTo(dataValue, filterValue),
169
+ autoRemove: (val) => testFalsy(val)
170
+ });
171
+ /**
172
+ * Keeps rows whose value is less than the filter value.
173
+ *
174
+ * This is implemented as the inverse of greater-than-or-equal comparison.
175
+ */
176
+ const filterFn_lessThan = constructFilterFn({
177
+ filter: (dataValue, filterValue) => !compareGreaterThanOrEqualTo(dataValue, filterValue),
178
+ autoRemove: (val) => testFalsy(val)
179
+ });
180
+ /**
181
+ * Keeps rows whose value is less than or equal to the filter value.
182
+ *
183
+ * This is implemented as the inverse of greater-than comparison.
184
+ */
185
+ const filterFn_lessThanOrEqualTo = constructFilterFn({
186
+ filter: (dataValue, filterValue) => !compareGreaterThan(dataValue, filterValue),
187
+ autoRemove: (val) => testFalsy(val)
188
+ });
189
+ /**
190
+ * Keeps rows whose value falls between an exclusive min/max pair.
191
+ *
192
+ * Blank range endpoints are treated as open-ended.
193
+ */
194
+ const filterFn_between = constructFilterFn({
195
+ filter: (dataValue, filterValues) => compareBetween(dataValue, filterValues, false),
196
+ autoRemove: (val) => testFalsy(val) || Array.isArray(val) && testFalsy(val[0]) && testFalsy(val[1])
197
+ });
198
+ /**
199
+ * Keeps rows whose value falls between an inclusive min/max pair.
200
+ *
201
+ * Blank range endpoints are treated as open-ended.
202
+ */
203
+ const filterFn_betweenInclusive = constructFilterFn({
204
+ filter: (dataValue, filterValues) => compareBetween(dataValue, filterValues, true),
205
+ autoRemove: (val) => testFalsy(val) || Array.isArray(val) && testFalsy(val[0]) && testFalsy(val[1])
206
+ });
207
+ /**
208
+ * Keeps rows whose numeric value is inside an inclusive `[min, max]` range.
209
+ *
210
+ * Filter values are normalized so blank endpoints become open-ended and
211
+ * reversed endpoints are swapped.
212
+ */
213
+ const filterFn_inNumberRange = constructFilterFn({
214
+ filter: (dataValue, filterValue) => {
215
+ const [min, max] = filterValue;
216
+ return dataValue >= min && dataValue <= max;
217
+ },
218
+ resolveFilterValue: (val) => {
219
+ const [unsafeMin, unsafeMax] = val;
220
+ const parsedMin = typeof unsafeMin !== "number" ? parseFloat(unsafeMin) : unsafeMin;
221
+ const parsedMax = typeof unsafeMax !== "number" ? parseFloat(unsafeMax) : unsafeMax;
222
+ let min = unsafeMin === null || Number.isNaN(parsedMin) ? -Infinity : parsedMin;
223
+ let max = unsafeMax === null || Number.isNaN(parsedMax) ? Infinity : parsedMax;
224
+ if (min > max) {
225
+ const temp = min;
226
+ min = max;
227
+ max = temp;
228
+ }
229
+ return [min, max];
230
+ },
231
+ autoRemove: (val) => testFalsy(val) || Array.isArray(val) && testFalsy(val[0]) && testFalsy(val[1])
232
+ });
233
+ /**
234
+ * Keeps rows whose date value is inside an inclusive `[min, max]` date range.
235
+ *
236
+ * Row values and range endpoints may be `Date` objects, timestamps, or
237
+ * parseable date strings. Blank or invalid endpoints become open-ended and
238
+ * reversed endpoints are swapped. Rows without a valid date never match.
239
+ */
240
+ const filterFn_inDateRange = constructFilterFn({
241
+ filter: (dataValue, filterValue) => {
242
+ const [min, max] = filterValue;
243
+ return dataValue >= min && dataValue <= max;
244
+ },
245
+ resolveFilterValue: (val) => {
246
+ const [unsafeMin, unsafeMax] = val;
247
+ const parsedMin = toDateTimestamp(unsafeMin);
248
+ const parsedMax = toDateTimestamp(unsafeMax);
249
+ let min = Number.isNaN(parsedMin) ? -Infinity : parsedMin;
250
+ let max = Number.isNaN(parsedMax) ? Infinity : parsedMax;
251
+ if (min > max) {
252
+ const temp = min;
253
+ min = max;
254
+ max = temp;
255
+ }
256
+ return [min, max];
257
+ },
258
+ resolveDataValue: (val) => toDateTimestamp(val),
259
+ autoRemove: (val) => testFalsy(val) || Array.isArray(val) && testFalsy(val[0]) && testFalsy(val[1])
260
+ });
261
+ /**
262
+ * Keeps rows whose scalar column value equals at least one filter value.
263
+ */
264
+ const filterFn_arrHas = constructFilterFn({
265
+ filter: (dataValue, filterValue) => {
266
+ for (let i = 0; i < filterValue.length; i++) if (dataValue === filterValue[i]) return true;
267
+ return false;
268
+ },
269
+ autoRemove: (val) => testFalsy(val) || !val?.length
270
+ });
271
+ /**
272
+ * Keeps rows whose array or string column value includes at least one filter value.
273
+ */
274
+ const filterFn_arrIncludes = constructFilterFn({
275
+ filter: (dataValue, filterValue) => {
276
+ if (typeof dataValue !== "string" && !Array.isArray(dataValue)) return false;
277
+ for (let i = 0; i < filterValue.length; i++) if (dataValue.includes(filterValue[i])) return true;
278
+ return false;
279
+ },
280
+ autoRemove: (val) => testFalsy(val) || !val?.length
281
+ });
282
+ /**
283
+ * Keeps rows whose array column value includes every filter value.
284
+ */
285
+ const filterFn_arrIncludesAll = constructFilterFn({
286
+ filter: (dataValue, filterValue) => {
287
+ if (!Array.isArray(dataValue)) return false;
288
+ for (let i = 0; i < filterValue.length; i++) if (!dataValue.includes(filterValue[i])) return false;
289
+ return true;
290
+ },
291
+ autoRemove: (val) => testFalsy(val) || !val?.length
292
+ });
293
+ /**
294
+ * Keeps rows whose array column value includes at least one filter value.
295
+ */
296
+ const filterFn_arrIncludesSome = constructFilterFn({
297
+ filter: (dataValue, filterValue) => {
298
+ if (!Array.isArray(dataValue)) return false;
299
+ for (let i = 0; i < filterValue.length; i++) if (dataValue.includes(filterValue[i])) return true;
300
+ return false;
301
+ },
302
+ autoRemove: (val) => testFalsy(val) || !val?.length
303
+ });
304
+ /**
305
+ * The built-in filter function registry.
306
+ *
307
+ * Registering this full object opts out of tree-shaking: every built-in
308
+ * filter function ends up in your bundle. Prefer importing the `filterFn_*`
309
+ * functions you actually use and registering just those in the `filterFns`
310
+ * slot, or passing them directly to the `filterFn` column option.
311
+ *
312
+ * @deprecated Import individual `filterFn_*` functions instead for a smaller
313
+ * bundle. This export still works and is not going away in v9, but built-in
314
+ * name resolution (including `filterFn: 'auto'`) only finds functions you
315
+ * register yourself.
316
+ */
317
+ const filterFns = {
318
+ arrIncludes: filterFn_arrIncludes,
319
+ arrIncludesAll: filterFn_arrIncludesAll,
320
+ arrHas: filterFn_arrHas,
321
+ arrIncludesSome: filterFn_arrIncludesSome,
322
+ between: filterFn_between,
323
+ betweenInclusive: filterFn_betweenInclusive,
324
+ empty: filterFn_empty,
325
+ endsWith: filterFn_endsWith,
326
+ equals: filterFn_equals,
327
+ equalsString: filterFn_equalsString,
328
+ equalsStringSensitive: filterFn_equalsStringSensitive,
329
+ inDateRange: filterFn_inDateRange,
330
+ inNumberRange: filterFn_inNumberRange,
331
+ includesString: filterFn_includesString,
332
+ includesStringSensitive: filterFn_includesStringSensitive,
333
+ notEmpty: filterFn_notEmpty,
334
+ startsWith: filterFn_startsWith,
335
+ weakEquals: filterFn_weakEquals
336
+ };
337
+ function testFalsy(val) {
338
+ return val === void 0 || val === null || val === "";
339
+ }
340
+ function testValueEmpty(dataValue) {
341
+ return dataValue == null || String(dataValue).trim() === "";
342
+ }
343
+ function toDateTimestamp(value) {
344
+ if (value instanceof Date) return value.getTime();
345
+ if (typeof value === "number") return value;
346
+ if (value == null || value === "") return NaN;
347
+ return new Date(value).getTime();
348
+ }
349
+ function compareGreaterThan(dataValue, filterValue) {
350
+ const numericDataValue = dataValue == null ? 0 : +dataValue;
351
+ const numericFilterValue = Number(filterValue);
352
+ if (!isNaN(numericFilterValue) && !isNaN(numericDataValue)) return numericDataValue > numericFilterValue;
353
+ return String(dataValue ?? "").toLowerCase().trim() > String(filterValue).toLowerCase().trim();
354
+ }
355
+ function compareGreaterThanOrEqualTo(dataValue, filterValue) {
356
+ return dataValue === filterValue || compareGreaterThan(dataValue, filterValue);
357
+ }
358
+ function compareBetween(dataValue, filterValues, inclusive) {
359
+ const min = filterValues[0];
360
+ const hasMin = min !== "" && min !== void 0;
361
+ if (hasMin) {
362
+ if (!(inclusive ? compareGreaterThanOrEqualTo(dataValue, min) : compareGreaterThan(dataValue, min))) return false;
363
+ }
364
+ const max = filterValues[1];
365
+ if (max === "" || max === void 0) return true;
366
+ if (hasMin) {
367
+ const numericMin = Number(min);
368
+ const numericMax = Number(max);
369
+ if (!isNaN(numericMin) && !isNaN(numericMax) && numericMin > numericMax) return true;
370
+ }
371
+ return inclusive ? !compareGreaterThan(dataValue, max) : !compareGreaterThanOrEqualTo(dataValue, max);
372
+ }
373
+
374
+ //#endregion
375
+ exports.constructFilterFn = constructFilterFn;
376
+ exports.filterFn_arrHas = filterFn_arrHas;
377
+ exports.filterFn_arrIncludes = filterFn_arrIncludes;
378
+ exports.filterFn_arrIncludesAll = filterFn_arrIncludesAll;
379
+ exports.filterFn_arrIncludesSome = filterFn_arrIncludesSome;
380
+ exports.filterFn_between = filterFn_between;
381
+ exports.filterFn_betweenInclusive = filterFn_betweenInclusive;
382
+ exports.filterFn_empty = filterFn_empty;
383
+ exports.filterFn_endsWith = filterFn_endsWith;
384
+ exports.filterFn_equals = filterFn_equals;
385
+ exports.filterFn_equalsString = filterFn_equalsString;
386
+ exports.filterFn_equalsStringSensitive = filterFn_equalsStringSensitive;
387
+ exports.filterFn_greaterThan = filterFn_greaterThan;
388
+ exports.filterFn_greaterThanOrEqualTo = filterFn_greaterThanOrEqualTo;
389
+ exports.filterFn_inDateRange = filterFn_inDateRange;
390
+ exports.filterFn_inNumberRange = filterFn_inNumberRange;
391
+ exports.filterFn_includesString = filterFn_includesString;
392
+ exports.filterFn_includesStringSensitive = filterFn_includesStringSensitive;
393
+ exports.filterFn_lessThan = filterFn_lessThan;
394
+ exports.filterFn_lessThanOrEqualTo = filterFn_lessThanOrEqualTo;
395
+ exports.filterFn_notEmpty = filterFn_notEmpty;
396
+ exports.filterFn_startsWith = filterFn_startsWith;
397
+ exports.filterFn_weakEquals = filterFn_weakEquals;
398
+ exports.filterFns = filterFns;
399
+ //# sourceMappingURL=filterFns.cjs.map