@hybridly/vue 0.5.4 → 0.5.6

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.
package/dist/index.cjs CHANGED
@@ -1053,22 +1053,37 @@ function useRefinements(properties, refinementsKeys, defaultOptions = {}) {
1053
1053
  return;
1054
1054
  }
1055
1055
  const next = options?.direction ? sort[options?.direction] : sort.next;
1056
+ const sortData = next ? options?.sortData ?? {} : Object.fromEntries(Object.entries(options?.sortData ?? {}).map(([key, _]) => [key, void 0]));
1056
1057
  return await core.router.reload({
1057
1058
  ...defaultOptions,
1058
1059
  ...options,
1059
1060
  data: {
1060
- [sortsKey.value]: next || void 0
1061
+ [sortsKey.value]: next || void 0,
1062
+ ...sortData
1061
1063
  }
1062
1064
  });
1063
1065
  }
1064
1066
  function bindFilter(name, options = {}) {
1067
+ const debounce = options.debounce ?? 250;
1068
+ const refDebounce = options.syncDebounce ?? 250;
1065
1069
  const transform = options?.transformValue ?? ((value) => value);
1066
1070
  const watchFn = options?.watch ?? vue.watch;
1067
- const _ref = vue.ref(transform(refinements.value.filters.find((f) => f.name === name)?.value));
1071
+ const getFilterValue = () => transform(refinements.value.filters.find((f) => f.name === name)?.value);
1072
+ const _ref = vue.ref(getFilterValue());
1073
+ let _filterTimeout;
1074
+ let _refTimeout;
1068
1075
  vue.watch(() => refinements.value.filters.find((f) => f.name === name), (filter) => {
1069
- _ref.value = transform(filter?.value);
1076
+ clearTimeout(_refTimeout);
1077
+ _refTimeout = setTimeout(() => _ref.value = transform(filter?.value), refDebounce);
1070
1078
  }, { deep: true });
1071
- watchFn(_ref, (value) => applyFilter(name, transform(value), options));
1079
+ watchFn(_ref, (value) => {
1080
+ clearTimeout(_refTimeout);
1081
+ clearTimeout(_filterTimeout);
1082
+ _filterTimeout = setTimeout(() => {
1083
+ clearTimeout(_refTimeout);
1084
+ applyFilter(name, transform(value), options);
1085
+ }, debounce);
1086
+ });
1072
1087
  return _ref;
1073
1088
  }
1074
1089
  return {
@@ -1360,6 +1375,23 @@ function useTable(props, key, defaultOptions = {}) {
1360
1375
  });
1361
1376
  }
1362
1377
 
1378
+ function useQueryParameters() {
1379
+ const state = vue.reactive({});
1380
+ function updateState() {
1381
+ const params = new URLSearchParams(window.location.search);
1382
+ const unusedKeys = new Set(Object.keys(state));
1383
+ for (const key of params.keys()) {
1384
+ const paramsForKey = params.getAll(key);
1385
+ state[key] = paramsForKey.length > 1 ? paramsForKey : params.get(key) || "";
1386
+ unusedKeys.delete(key);
1387
+ }
1388
+ Array.from(unusedKeys).forEach((key) => delete state[key]);
1389
+ }
1390
+ updateState();
1391
+ hybridly.registerHook("after", updateState);
1392
+ return state;
1393
+ }
1394
+
1363
1395
  exports.can = core.can;
1364
1396
  exports.route = core.route;
1365
1397
  exports.router = core.router;
@@ -1377,6 +1409,7 @@ exports.useForm = useForm;
1377
1409
  exports.useHistoryState = useHistoryState;
1378
1410
  exports.useProperties = useProperties;
1379
1411
  exports.useProperty = useProperty;
1412
+ exports.useQueryParameters = useQueryParameters;
1380
1413
  exports.useRefinements = useRefinements;
1381
1414
  exports.useRoute = useRoute;
1382
1415
  exports.useTable = useTable;
package/dist/index.d.cts CHANGED
@@ -5,7 +5,7 @@ import { RouterContextOptions, Plugin as Plugin$1, RouterContext, Method as Meth
5
5
  export { can, route, router } from '@hybridly/core';
6
6
  import { Axios, AxiosResponse, AxiosProgressEvent } from 'axios';
7
7
  import * as _vue_shared from '@vue/shared';
8
- import { RequestData } from '@hybridly/utils';
8
+ import { RequestData, FormDataConvertible } from '@hybridly/utils';
9
9
  import { SearchableObject, Path, PathValue } from '@clickbar/dot-diver';
10
10
  import * as hybridly from 'hybridly';
11
11
 
@@ -713,11 +713,25 @@ type SortDirection = 'asc' | 'desc';
713
713
  type AvailableHybridRequestOptions = Omit<HybridRequestOptions$1, 'url' | 'data'>;
714
714
  interface ToggleSortOptions extends AvailableHybridRequestOptions {
715
715
  direction?: SortDirection;
716
+ /** Additional sort data, only applied when sorting. */
717
+ sortData?: {
718
+ [key: string]: FormDataConvertible;
719
+ };
716
720
  }
717
721
  interface BindFilterOptions<T> extends AvailableHybridRequestOptions {
718
722
  transformValue?: (value?: T) => any;
719
723
  /** If specified, this callback will watch the ref and apply */
720
724
  watch?: (ref: Ref<T>, cb: any) => void;
725
+ /**
726
+ * The debounce time in milliseconds for updating this filter.
727
+ * @default 250ms
728
+ */
729
+ debounce?: number;
730
+ /**
731
+ * The debounce time in milliseconds for updating the ref.
732
+ * @default 250ms
733
+ */
734
+ syncDebounce?: number;
721
735
  }
722
736
  declare global {
723
737
  interface FilterRefinement {
@@ -1221,4 +1235,11 @@ declare function useTable<RecordType extends (Props[PropsKey] extends Table<infe
1221
1235
  paginator: Exclude<PaginatorKindName extends "cursor" ? CursorPaginator<RecordType> : PaginatorKindName extends "simple" ? SimplePaginator<RecordType> : Paginator<RecordType>, "data">;
1222
1236
  };
1223
1237
 
1224
- export { type Action, type AvailableHybridRequestOptions, type BindFilterOptions, type BulkAction, type BulkSelection, type Column, type InlineAction, type Layout, type RecordIdentifier, RouterLink, type SortDirection, type ToggleSortOptions, defineLayout, defineLayoutProperties, initializeHybridly, registerHook, setProperty, useBackForward, useBulkSelect, useContext, useDialog, useForm, useHistoryState, useProperties, useProperty, useRefinements, useRoute, useTable };
1238
+ /**
1239
+ * Access reactive query parameters.
1240
+ *
1241
+ * @see https://hybridly.dev/api/utils/use-query-parameters.html
1242
+ */
1243
+ declare function useQueryParameters<T extends Record<string, any> = Record<string, any>>(): T;
1244
+
1245
+ export { type Action, type AvailableHybridRequestOptions, type BindFilterOptions, type BulkAction, type BulkSelection, type Column, type InlineAction, type Layout, type RecordIdentifier, RouterLink, type SortDirection, type ToggleSortOptions, defineLayout, defineLayoutProperties, initializeHybridly, registerHook, setProperty, useBackForward, useBulkSelect, useContext, useDialog, useForm, useHistoryState, useProperties, useProperty, useQueryParameters, useRefinements, useRoute, useTable };
package/dist/index.d.mts CHANGED
@@ -5,7 +5,7 @@ import { RouterContextOptions, Plugin as Plugin$1, RouterContext, Method as Meth
5
5
  export { can, route, router } from '@hybridly/core';
6
6
  import { Axios, AxiosResponse, AxiosProgressEvent } from 'axios';
7
7
  import * as _vue_shared from '@vue/shared';
8
- import { RequestData } from '@hybridly/utils';
8
+ import { RequestData, FormDataConvertible } from '@hybridly/utils';
9
9
  import { SearchableObject, Path, PathValue } from '@clickbar/dot-diver';
10
10
  import * as hybridly from 'hybridly';
11
11
 
@@ -713,11 +713,25 @@ type SortDirection = 'asc' | 'desc';
713
713
  type AvailableHybridRequestOptions = Omit<HybridRequestOptions$1, 'url' | 'data'>;
714
714
  interface ToggleSortOptions extends AvailableHybridRequestOptions {
715
715
  direction?: SortDirection;
716
+ /** Additional sort data, only applied when sorting. */
717
+ sortData?: {
718
+ [key: string]: FormDataConvertible;
719
+ };
716
720
  }
717
721
  interface BindFilterOptions<T> extends AvailableHybridRequestOptions {
718
722
  transformValue?: (value?: T) => any;
719
723
  /** If specified, this callback will watch the ref and apply */
720
724
  watch?: (ref: Ref<T>, cb: any) => void;
725
+ /**
726
+ * The debounce time in milliseconds for updating this filter.
727
+ * @default 250ms
728
+ */
729
+ debounce?: number;
730
+ /**
731
+ * The debounce time in milliseconds for updating the ref.
732
+ * @default 250ms
733
+ */
734
+ syncDebounce?: number;
721
735
  }
722
736
  declare global {
723
737
  interface FilterRefinement {
@@ -1221,4 +1235,11 @@ declare function useTable<RecordType extends (Props[PropsKey] extends Table<infe
1221
1235
  paginator: Exclude<PaginatorKindName extends "cursor" ? CursorPaginator<RecordType> : PaginatorKindName extends "simple" ? SimplePaginator<RecordType> : Paginator<RecordType>, "data">;
1222
1236
  };
1223
1237
 
1224
- export { type Action, type AvailableHybridRequestOptions, type BindFilterOptions, type BulkAction, type BulkSelection, type Column, type InlineAction, type Layout, type RecordIdentifier, RouterLink, type SortDirection, type ToggleSortOptions, defineLayout, defineLayoutProperties, initializeHybridly, registerHook, setProperty, useBackForward, useBulkSelect, useContext, useDialog, useForm, useHistoryState, useProperties, useProperty, useRefinements, useRoute, useTable };
1238
+ /**
1239
+ * Access reactive query parameters.
1240
+ *
1241
+ * @see https://hybridly.dev/api/utils/use-query-parameters.html
1242
+ */
1243
+ declare function useQueryParameters<T extends Record<string, any> = Record<string, any>>(): T;
1244
+
1245
+ export { type Action, type AvailableHybridRequestOptions, type BindFilterOptions, type BulkAction, type BulkSelection, type Column, type InlineAction, type Layout, type RecordIdentifier, RouterLink, type SortDirection, type ToggleSortOptions, defineLayout, defineLayoutProperties, initializeHybridly, registerHook, setProperty, useBackForward, useBulkSelect, useContext, useDialog, useForm, useHistoryState, useProperties, useProperty, useQueryParameters, useRefinements, useRoute, useTable };
package/dist/index.d.ts CHANGED
@@ -5,7 +5,7 @@ import { RouterContextOptions, Plugin as Plugin$1, RouterContext, Method as Meth
5
5
  export { can, route, router } from '@hybridly/core';
6
6
  import { Axios, AxiosResponse, AxiosProgressEvent } from 'axios';
7
7
  import * as _vue_shared from '@vue/shared';
8
- import { RequestData } from '@hybridly/utils';
8
+ import { RequestData, FormDataConvertible } from '@hybridly/utils';
9
9
  import { SearchableObject, Path, PathValue } from '@clickbar/dot-diver';
10
10
  import * as hybridly from 'hybridly';
11
11
 
@@ -713,11 +713,25 @@ type SortDirection = 'asc' | 'desc';
713
713
  type AvailableHybridRequestOptions = Omit<HybridRequestOptions$1, 'url' | 'data'>;
714
714
  interface ToggleSortOptions extends AvailableHybridRequestOptions {
715
715
  direction?: SortDirection;
716
+ /** Additional sort data, only applied when sorting. */
717
+ sortData?: {
718
+ [key: string]: FormDataConvertible;
719
+ };
716
720
  }
717
721
  interface BindFilterOptions<T> extends AvailableHybridRequestOptions {
718
722
  transformValue?: (value?: T) => any;
719
723
  /** If specified, this callback will watch the ref and apply */
720
724
  watch?: (ref: Ref<T>, cb: any) => void;
725
+ /**
726
+ * The debounce time in milliseconds for updating this filter.
727
+ * @default 250ms
728
+ */
729
+ debounce?: number;
730
+ /**
731
+ * The debounce time in milliseconds for updating the ref.
732
+ * @default 250ms
733
+ */
734
+ syncDebounce?: number;
721
735
  }
722
736
  declare global {
723
737
  interface FilterRefinement {
@@ -1221,4 +1235,11 @@ declare function useTable<RecordType extends (Props[PropsKey] extends Table<infe
1221
1235
  paginator: Exclude<PaginatorKindName extends "cursor" ? CursorPaginator<RecordType> : PaginatorKindName extends "simple" ? SimplePaginator<RecordType> : Paginator<RecordType>, "data">;
1222
1236
  };
1223
1237
 
1224
- export { type Action, type AvailableHybridRequestOptions, type BindFilterOptions, type BulkAction, type BulkSelection, type Column, type InlineAction, type Layout, type RecordIdentifier, RouterLink, type SortDirection, type ToggleSortOptions, defineLayout, defineLayoutProperties, initializeHybridly, registerHook, setProperty, useBackForward, useBulkSelect, useContext, useDialog, useForm, useHistoryState, useProperties, useProperty, useRefinements, useRoute, useTable };
1238
+ /**
1239
+ * Access reactive query parameters.
1240
+ *
1241
+ * @see https://hybridly.dev/api/utils/use-query-parameters.html
1242
+ */
1243
+ declare function useQueryParameters<T extends Record<string, any> = Record<string, any>>(): T;
1244
+
1245
+ export { type Action, type AvailableHybridRequestOptions, type BindFilterOptions, type BulkAction, type BulkSelection, type Column, type InlineAction, type Layout, type RecordIdentifier, RouterLink, type SortDirection, type ToggleSortOptions, defineLayout, defineLayoutProperties, initializeHybridly, registerHook, setProperty, useBackForward, useBulkSelect, useContext, useDialog, useForm, useHistoryState, useProperties, useProperty, useQueryParameters, useRefinements, useRoute, useTable };
package/dist/index.mjs CHANGED
@@ -7,7 +7,7 @@ import { setupDevtoolsPlugin } from '@vue/devtools-api';
7
7
  import qs from 'qs';
8
8
  import { getByPath, setByPath } from '@clickbar/dot-diver';
9
9
  import isEqual from 'lodash.isequal';
10
- import { router as router$1, route } from 'hybridly';
10
+ import { router as router$1, route, registerHook as registerHook$2 } from 'hybridly';
11
11
 
12
12
  function progress(options) {
13
13
  const resolved = {
@@ -1046,22 +1046,37 @@ function useRefinements(properties, refinementsKeys, defaultOptions = {}) {
1046
1046
  return;
1047
1047
  }
1048
1048
  const next = options?.direction ? sort[options?.direction] : sort.next;
1049
+ const sortData = next ? options?.sortData ?? {} : Object.fromEntries(Object.entries(options?.sortData ?? {}).map(([key, _]) => [key, void 0]));
1049
1050
  return await router.reload({
1050
1051
  ...defaultOptions,
1051
1052
  ...options,
1052
1053
  data: {
1053
- [sortsKey.value]: next || void 0
1054
+ [sortsKey.value]: next || void 0,
1055
+ ...sortData
1054
1056
  }
1055
1057
  });
1056
1058
  }
1057
1059
  function bindFilter(name, options = {}) {
1060
+ const debounce = options.debounce ?? 250;
1061
+ const refDebounce = options.syncDebounce ?? 250;
1058
1062
  const transform = options?.transformValue ?? ((value) => value);
1059
1063
  const watchFn = options?.watch ?? watch;
1060
- const _ref = ref(transform(refinements.value.filters.find((f) => f.name === name)?.value));
1064
+ const getFilterValue = () => transform(refinements.value.filters.find((f) => f.name === name)?.value);
1065
+ const _ref = ref(getFilterValue());
1066
+ let _filterTimeout;
1067
+ let _refTimeout;
1061
1068
  watch(() => refinements.value.filters.find((f) => f.name === name), (filter) => {
1062
- _ref.value = transform(filter?.value);
1069
+ clearTimeout(_refTimeout);
1070
+ _refTimeout = setTimeout(() => _ref.value = transform(filter?.value), refDebounce);
1063
1071
  }, { deep: true });
1064
- watchFn(_ref, (value) => applyFilter(name, transform(value), options));
1072
+ watchFn(_ref, (value) => {
1073
+ clearTimeout(_refTimeout);
1074
+ clearTimeout(_filterTimeout);
1075
+ _filterTimeout = setTimeout(() => {
1076
+ clearTimeout(_refTimeout);
1077
+ applyFilter(name, transform(value), options);
1078
+ }, debounce);
1079
+ });
1065
1080
  return _ref;
1066
1081
  }
1067
1082
  return {
@@ -1353,4 +1368,21 @@ function useTable(props, key, defaultOptions = {}) {
1353
1368
  });
1354
1369
  }
1355
1370
 
1356
- export { RouterLink, defineLayout, defineLayoutProperties, initializeHybridly, registerHook, setProperty, useBackForward, useBulkSelect, useContext, useDialog, useForm, useHistoryState, useProperties, useProperty, useRefinements, useRoute, useTable };
1371
+ function useQueryParameters() {
1372
+ const state = reactive({});
1373
+ function updateState() {
1374
+ const params = new URLSearchParams(window.location.search);
1375
+ const unusedKeys = new Set(Object.keys(state));
1376
+ for (const key of params.keys()) {
1377
+ const paramsForKey = params.getAll(key);
1378
+ state[key] = paramsForKey.length > 1 ? paramsForKey : params.get(key) || "";
1379
+ unusedKeys.delete(key);
1380
+ }
1381
+ Array.from(unusedKeys).forEach((key) => delete state[key]);
1382
+ }
1383
+ updateState();
1384
+ registerHook$2("after", updateState);
1385
+ return state;
1386
+ }
1387
+
1388
+ export { RouterLink, defineLayout, defineLayoutProperties, initializeHybridly, registerHook, setProperty, useBackForward, useBulkSelect, useContext, useDialog, useForm, useHistoryState, useProperties, useProperty, useQueryParameters, useRefinements, useRoute, useTable };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hybridly/vue",
3
- "version": "0.5.4",
3
+ "version": "0.5.6",
4
4
  "description": "Vue adapter for Hybridly",
5
5
  "keywords": [
6
6
  "hybridly",
@@ -39,20 +39,20 @@
39
39
  },
40
40
  "dependencies": {
41
41
  "@clickbar/dot-diver": "^1.0.1",
42
- "@vue/devtools-api": "^6.5.0",
43
- "defu": "^6.1.2",
42
+ "@vue/devtools-api": "^6.5.1",
43
+ "defu": "^6.1.3",
44
44
  "lodash.isequal": "^4.5.0",
45
45
  "nprogress": "^0.2.0",
46
46
  "qs": "^6.11.2",
47
- "@hybridly/core": "0.5.4",
48
- "@hybridly/utils": "0.5.4"
47
+ "@hybridly/utils": "0.5.6",
48
+ "@hybridly/core": "0.5.6"
49
49
  },
50
50
  "devDependencies": {
51
- "@types/lodash": "^4.14.199",
52
- "@types/lodash.clonedeep": "^4.5.7",
53
- "@types/lodash.isequal": "^4.5.6",
54
- "@types/nprogress": "^0.2.1",
55
- "vue": "^3.3.4"
51
+ "@types/lodash": "^4.14.200",
52
+ "@types/lodash.clonedeep": "^4.5.8",
53
+ "@types/lodash.isequal": "^4.5.7",
54
+ "@types/nprogress": "^0.2.2",
55
+ "vue": "^3.3.7"
56
56
  },
57
57
  "scripts": {
58
58
  "build": "unbuild",