UNPKG

@veebisepad/vue-query-filters

Version:

Reactive utility for managing URL query parameters in Vue 3.

81 lines (80 loc) 3.19 kB
import { reactive } from 'vue'; /** * Creates a reactive filter object from filter configurations * @param filters Map of filter keys to their configurations * @param initialOptions Initial options for the filters * @returns Reactive filter object with values and methods */ export function useFilters(filters, initialOptions = {}) { const queryParams = new URLSearchParams(document.location.search); let options = { delimiter: ',', preserveQueryOrder: true, ...initialOptions }; const filterKeys = Object.keys(filters); const filterProps = Object.keys(filters).length > 0 ? Object.keys(filters).reduce((carry, key) => { const filterConfig = filters[key]; const transformedKey = filterConfig.transformKey(key); const paramValue = queryParams.get(transformedKey); carry[key] = filterConfig.parseQueryParam(paramValue, options.delimiter); return carry; }, {}) : {}; const hasCallback = !!options.onApply; const filterObject = { ...filterProps, toSearchParams() { return new URLSearchParams(this.toQueryObject()); }, get() { if (options.onApply) { options.onApply(options.preserveQueryOrder ? this.toOrderedQueryObject() : this.toQueryObject()); } else { console.warn('Cannot use get() - Filter callback is not set'); } }, toOrderedQueryObject(transformKeys = true) { const queryObject = this.toQueryObject(transformKeys); const orderedObject = {}; new URLSearchParams(document.location.search).forEach((_, key) => { if (key in queryObject) { orderedObject[key] = queryObject[key]; } }); return Object.assign(orderedObject, queryObject); }, toQueryObject(transformKeys = true) { return filterKeys.reduce((queryObject, key) => { const paramValue = filters[key].serializeQueryParam(this[key], options.delimiter); if (paramValue) { const objectKey = transformKeys ? filters[key].transformKey(key) : key; queryObject[objectKey] = paramValue; } return queryObject; }, {}); }, data() { return filterProps; }, has(filter, value) { return filters[filter].hasValue(this[filter], value) ?? false; }, clear(filterKey, shouldGet = true) { const filtersToClear = Array.isArray(filterKey) ? filterKey : [filterKey]; if (filtersToClear.length === 0) return; filtersToClear.forEach(key => { this[key] = filters[key].defaultValue; }); if (hasCallback && shouldGet) { this.get(); } }, clearAll() { this.clear(filterKeys, true); }, setOptions(newOptions) { options = { ...options, ...newOptions }; }, }; return reactive(filterObject); }