@veebisepad/vue-query-filters
Version:
Reactive utility for managing URL query parameters in Vue 3.
94 lines (93 loc) • 3.6 kB
JavaScript
/**
* Creates a collection of filter factory functions
* @returns Object containing filter factory methods
*/
export const createFilterFactory = (options) => {
const keyTransformer = options?.keyTransformer || ((key) => key);
/**
* Transforms a key using the provided key transformer function
* @param key The key to wrap
* @returns The transformed key
*/
const transformKey = (key) => keyTransformer(key);
const allowedFilters = {
/**
* Creates a filter for a single value
* @template SingleType Type of the filter value
* @param defaultValue Default value when filter key is not present
* @returns A filter object handling single values
*/
single: (defaultValue = null) => ({
defaultValue,
parseQueryParam(value) {
return !value ? this.defaultValue : value;
},
serializeQueryParam(value) {
return !value ? null : String(value);
},
hasValue(filterValue, value) {
return filterValue?.toString() === value.toString();
},
transformKey,
}),
/**
* Creates a filter for multiple values
* @template MultipleType Type of each item in the array
* @param defaultValue Default array when filter key is not present
* @returns A filter object handling arrays
*/
multiple: (defaultValue = []) => ({
defaultValue,
parseQueryParam(value, delimiter) {
return !value ? this.defaultValue : value.split(delimiter);
},
serializeQueryParam(value, delimiter) {
return !Array.isArray(value) || !value.length ? null : value.join(delimiter);
},
hasValue(filterValue, value) {
return Array.isArray(filterValue) ? filterValue.includes(value) : false;
},
transformKey,
}),
/**
* Creates a range filter
* @template RangeType Type of the range endpoints
* @param defaultValue Default range when filter key is not present
* @returns A filter object handling { from: RangeType; to: RangeType }
*/
range: (defaultValue = { from: null, to: null }) => ({
defaultValue,
parseQueryParam(value, delimiter) {
if (!value)
return this.defaultValue;
const [from, to] = value.split(delimiter);
return {
from: from ? from : this.defaultValue.from,
to: to ? to : this.defaultValue.to,
};
},
serializeQueryParam(value, delimiter) {
if (!value || (value.from === null && value.to === null))
return null;
return [value.from, value.to].join(delimiter);
},
hasValue(filterValue, value) {
return filterValue?.from?.toString() === value.toString() || filterValue?.to?.toString() === value.toString();
},
transformKey,
}),
/**
* Allows creating a custom filter
* @template CustomType Type of the filter value
* @param filter A fully-defined filter object
* @returns The same filter, for custom scenarios
*/
custom: (filter) => {
return {
...filter,
transformKey,
};
},
};
return allowedFilters;
};