@hybridly/vue 0.7.10 → 0.7.11

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
@@ -947,7 +947,7 @@ function useDialog() {
947
947
  /** Unmounts the dialog. Should be called after its closing animations. */
948
948
  unmount: () => dialogStore.removeComponent(),
949
949
  /** Whether the dialog is shown. */
950
- show: vue.computed(() => dialogStore.state.show.value),
950
+ show: vue.computed({ get: () => dialogStore.state.show.value, set: (v) => !v ? core.router.dialog.close({ local: true }) : null }),
951
951
  /** Properties of the dialog. */
952
952
  properties: vue.computed(() => state.context.value?.dialog?.properties)
953
953
  };
@@ -1186,15 +1186,19 @@ function useRefinements(properties, refinementsKeys, defaultOptions = {}) {
1186
1186
  };
1187
1187
  }
1188
1188
 
1189
+ const isNavigating = vue.ref(false);
1189
1190
  function useRoute() {
1190
1191
  const current = vue.ref(core.router.current());
1191
1192
  function matches(name, parameters) {
1192
1193
  return core.router.matches(vue.toValue(name), parameters);
1193
1194
  }
1195
+ registerHook("before", () => isNavigating.value = true);
1196
+ registerHook("after", () => isNavigating.value = false);
1194
1197
  registerHook("navigated", () => {
1195
1198
  current.value = core.router.current();
1196
1199
  });
1197
1200
  return {
1201
+ isNavigating: vue.readonly(isNavigating),
1198
1202
  current: vue.readonly(current),
1199
1203
  matches
1200
1204
  };
@@ -1322,7 +1326,7 @@ function useTable(props, key, defaultOptions = {}) {
1322
1326
  /** Deselects records on the current page. */
1323
1327
  deselectPage: () => bulk.deselect(...table.value.records.map((record) => getRecordKey(record))),
1324
1328
  /** Whether all records on the current page are selected. */
1325
- isPageSelected: vue.computed(() => table.value.records.every((record) => bulk.selected(getRecordKey(record)))),
1329
+ isPageSelected: vue.computed(() => table.value.records.length > 0 && table.value.records.every((record) => bulk.selected(getRecordKey(record)))),
1326
1330
  /** Checks if the given record is selected. */
1327
1331
  isSelected: (record) => bulk.selected(getRecordKey(record)),
1328
1332
  /** Whether all records are selected. */
@@ -1418,6 +1422,28 @@ function useQueryParameters() {
1418
1422
  core.registerHook("after", updateState);
1419
1423
  return state;
1420
1424
  }
1425
+ function useQueryParameter(name, options = {}) {
1426
+ const query = useQueryParameters();
1427
+ const transform = (value2) => {
1428
+ if (options.transform === "bool") {
1429
+ return value2 === true || value2 === "true" || value2 === "1" || value2 === "yes";
1430
+ } else if (options.transform === "number") {
1431
+ return Number(value2);
1432
+ } else if (options.transform === "string") {
1433
+ return String(value2);
1434
+ } else if (options.transform === "date") {
1435
+ return new Date(value2);
1436
+ } else if (typeof options.transform === "function") {
1437
+ return options.transform(value2);
1438
+ }
1439
+ return value2;
1440
+ };
1441
+ const value = vue.ref();
1442
+ vue.watch(query, () => {
1443
+ value.value = transform(query[name] ?? vue.toValue(options.defaultValue));
1444
+ }, { deep: true, immediate: true });
1445
+ return value;
1446
+ }
1421
1447
 
1422
1448
  exports.can = core.can;
1423
1449
  exports.route = core.route;
@@ -1433,6 +1459,7 @@ exports.useForm = useForm;
1433
1459
  exports.useHistoryState = useHistoryState;
1434
1460
  exports.useProperties = useProperties;
1435
1461
  exports.useProperty = useProperty;
1462
+ exports.useQueryParameter = useQueryParameter;
1436
1463
  exports.useQueryParameters = useQueryParameters;
1437
1464
  exports.useRefinements = useRefinements;
1438
1465
  exports.useRoute = useRoute;
package/dist/index.d.cts CHANGED
@@ -224,7 +224,7 @@ declare function useDialog(): {
224
224
  /** Unmounts the dialog. Should be called after its closing animations. */
225
225
  unmount: () => void;
226
226
  /** Whether the dialog is shown. */
227
- show: vue.ComputedRef<boolean | undefined>;
227
+ show: vue.WritableComputedRef<boolean | undefined>;
228
228
  /** Properties of the dialog. */
229
229
  properties: vue.ComputedRef<Properties | undefined>;
230
230
  };
@@ -522,6 +522,7 @@ declare function useRefinements<Properties extends object, RefinementsKey extend
522
522
  };
523
523
 
524
524
  declare function useRoute(): {
525
+ isNavigating: Readonly<vue.Ref<boolean>>;
525
526
  current: Readonly<vue.Ref<string | undefined>>;
526
527
  matches: <T extends RouteName>(name: MaybeRefOrGetter<T>, parameters?: RouteParameters<T>) => boolean;
527
528
  };
@@ -744,6 +745,35 @@ declare function useTable<RecordType extends (Props[PropsKey] extends Table<infe
744
745
  * @see https://hybridly.dev/api/utils/use-query-parameters.html
745
746
  */
746
747
  declare function useQueryParameters<T extends Record<string, any> = Record<string, any>>(): T;
748
+ type RouteParameter = string | number | boolean | null | undefined;
749
+ type TransformFunction<V extends RouteParameter, R> = (val: V) => R;
750
+ type TransformType<T extends RouteParameter, O> = O extends {
751
+ transform: 'number';
752
+ } ? number : O extends {
753
+ transform: 'bool';
754
+ } ? boolean : O extends {
755
+ transform: 'string';
756
+ } ? string : O extends {
757
+ transform: 'date';
758
+ } ? Date : O extends {
759
+ transform: TransformFunction<T, infer R>;
760
+ } ? R : T;
761
+ interface UseQueryParameterOptions<V extends RouteParameter, R> {
762
+ /**
763
+ * Specifies a default value if the query parameter does not exist.
764
+ */
765
+ defaultValue?: MaybeRefOrGetter<R>;
766
+ /**
767
+ * Transforms the query parameter.
768
+ */
769
+ transform?: 'number' | 'bool' | 'string' | 'date' | TransformFunction<V, R>;
770
+ }
771
+ /**
772
+ * Makes the specified query parameter reactive.
773
+ *
774
+ * @see https://hybridly.dev/api/utils/use-query-parameter.html
775
+ */
776
+ declare function useQueryParameter<ParameterType extends RouteParameter = RouteParameter, Options extends UseQueryParameterOptions<ParameterType, any> = UseQueryParameterOptions<ParameterType, ParameterType>>(name: string, options?: Options): Ref<TransformType<ParameterType, Options>>;
747
777
 
748
778
  /**
749
779
  * Initializes Hybridly's router and context.
@@ -921,4 +951,4 @@ declare const RouterLink: vue.DefineComponent<{
921
951
  preload: boolean | "hover" | "mount";
922
952
  }, {}>;
923
953
 
924
- export { type Action, type AvailableHybridRequestOptions, type BindFilterOptions, type BulkAction, type BulkSelection, type Column, type DefaultFormOptions, type InitializeOptions, type InlineAction, type RecordIdentifier, RouterLink, type SortDirection, type ToggleSortOptions, initializeHybridly, registerHook, setProperty, useBackForward, useBulkSelect, useDialog, useForm, useHistoryState, useProperties, useProperty, useQueryParameters, useRefinements, useRoute, useTable };
954
+ export { type Action, type AvailableHybridRequestOptions, type BindFilterOptions, type BulkAction, type BulkSelection, type Column, type DefaultFormOptions, type InitializeOptions, type InlineAction, type RecordIdentifier, RouterLink, type SortDirection, type ToggleSortOptions, initializeHybridly, registerHook, setProperty, useBackForward, useBulkSelect, useDialog, useForm, useHistoryState, useProperties, useProperty, useQueryParameter, useQueryParameters, useRefinements, useRoute, useTable };
package/dist/index.d.mts CHANGED
@@ -224,7 +224,7 @@ declare function useDialog(): {
224
224
  /** Unmounts the dialog. Should be called after its closing animations. */
225
225
  unmount: () => void;
226
226
  /** Whether the dialog is shown. */
227
- show: vue.ComputedRef<boolean | undefined>;
227
+ show: vue.WritableComputedRef<boolean | undefined>;
228
228
  /** Properties of the dialog. */
229
229
  properties: vue.ComputedRef<Properties | undefined>;
230
230
  };
@@ -522,6 +522,7 @@ declare function useRefinements<Properties extends object, RefinementsKey extend
522
522
  };
523
523
 
524
524
  declare function useRoute(): {
525
+ isNavigating: Readonly<vue.Ref<boolean>>;
525
526
  current: Readonly<vue.Ref<string | undefined>>;
526
527
  matches: <T extends RouteName>(name: MaybeRefOrGetter<T>, parameters?: RouteParameters<T>) => boolean;
527
528
  };
@@ -744,6 +745,35 @@ declare function useTable<RecordType extends (Props[PropsKey] extends Table<infe
744
745
  * @see https://hybridly.dev/api/utils/use-query-parameters.html
745
746
  */
746
747
  declare function useQueryParameters<T extends Record<string, any> = Record<string, any>>(): T;
748
+ type RouteParameter = string | number | boolean | null | undefined;
749
+ type TransformFunction<V extends RouteParameter, R> = (val: V) => R;
750
+ type TransformType<T extends RouteParameter, O> = O extends {
751
+ transform: 'number';
752
+ } ? number : O extends {
753
+ transform: 'bool';
754
+ } ? boolean : O extends {
755
+ transform: 'string';
756
+ } ? string : O extends {
757
+ transform: 'date';
758
+ } ? Date : O extends {
759
+ transform: TransformFunction<T, infer R>;
760
+ } ? R : T;
761
+ interface UseQueryParameterOptions<V extends RouteParameter, R> {
762
+ /**
763
+ * Specifies a default value if the query parameter does not exist.
764
+ */
765
+ defaultValue?: MaybeRefOrGetter<R>;
766
+ /**
767
+ * Transforms the query parameter.
768
+ */
769
+ transform?: 'number' | 'bool' | 'string' | 'date' | TransformFunction<V, R>;
770
+ }
771
+ /**
772
+ * Makes the specified query parameter reactive.
773
+ *
774
+ * @see https://hybridly.dev/api/utils/use-query-parameter.html
775
+ */
776
+ declare function useQueryParameter<ParameterType extends RouteParameter = RouteParameter, Options extends UseQueryParameterOptions<ParameterType, any> = UseQueryParameterOptions<ParameterType, ParameterType>>(name: string, options?: Options): Ref<TransformType<ParameterType, Options>>;
747
777
 
748
778
  /**
749
779
  * Initializes Hybridly's router and context.
@@ -921,4 +951,4 @@ declare const RouterLink: vue.DefineComponent<{
921
951
  preload: boolean | "hover" | "mount";
922
952
  }, {}>;
923
953
 
924
- export { type Action, type AvailableHybridRequestOptions, type BindFilterOptions, type BulkAction, type BulkSelection, type Column, type DefaultFormOptions, type InitializeOptions, type InlineAction, type RecordIdentifier, RouterLink, type SortDirection, type ToggleSortOptions, initializeHybridly, registerHook, setProperty, useBackForward, useBulkSelect, useDialog, useForm, useHistoryState, useProperties, useProperty, useQueryParameters, useRefinements, useRoute, useTable };
954
+ export { type Action, type AvailableHybridRequestOptions, type BindFilterOptions, type BulkAction, type BulkSelection, type Column, type DefaultFormOptions, type InitializeOptions, type InlineAction, type RecordIdentifier, RouterLink, type SortDirection, type ToggleSortOptions, initializeHybridly, registerHook, setProperty, useBackForward, useBulkSelect, useDialog, useForm, useHistoryState, useProperties, useProperty, useQueryParameter, useQueryParameters, useRefinements, useRoute, useTable };
package/dist/index.d.ts CHANGED
@@ -224,7 +224,7 @@ declare function useDialog(): {
224
224
  /** Unmounts the dialog. Should be called after its closing animations. */
225
225
  unmount: () => void;
226
226
  /** Whether the dialog is shown. */
227
- show: vue.ComputedRef<boolean | undefined>;
227
+ show: vue.WritableComputedRef<boolean | undefined>;
228
228
  /** Properties of the dialog. */
229
229
  properties: vue.ComputedRef<Properties | undefined>;
230
230
  };
@@ -522,6 +522,7 @@ declare function useRefinements<Properties extends object, RefinementsKey extend
522
522
  };
523
523
 
524
524
  declare function useRoute(): {
525
+ isNavigating: Readonly<vue.Ref<boolean>>;
525
526
  current: Readonly<vue.Ref<string | undefined>>;
526
527
  matches: <T extends RouteName>(name: MaybeRefOrGetter<T>, parameters?: RouteParameters<T>) => boolean;
527
528
  };
@@ -744,6 +745,35 @@ declare function useTable<RecordType extends (Props[PropsKey] extends Table<infe
744
745
  * @see https://hybridly.dev/api/utils/use-query-parameters.html
745
746
  */
746
747
  declare function useQueryParameters<T extends Record<string, any> = Record<string, any>>(): T;
748
+ type RouteParameter = string | number | boolean | null | undefined;
749
+ type TransformFunction<V extends RouteParameter, R> = (val: V) => R;
750
+ type TransformType<T extends RouteParameter, O> = O extends {
751
+ transform: 'number';
752
+ } ? number : O extends {
753
+ transform: 'bool';
754
+ } ? boolean : O extends {
755
+ transform: 'string';
756
+ } ? string : O extends {
757
+ transform: 'date';
758
+ } ? Date : O extends {
759
+ transform: TransformFunction<T, infer R>;
760
+ } ? R : T;
761
+ interface UseQueryParameterOptions<V extends RouteParameter, R> {
762
+ /**
763
+ * Specifies a default value if the query parameter does not exist.
764
+ */
765
+ defaultValue?: MaybeRefOrGetter<R>;
766
+ /**
767
+ * Transforms the query parameter.
768
+ */
769
+ transform?: 'number' | 'bool' | 'string' | 'date' | TransformFunction<V, R>;
770
+ }
771
+ /**
772
+ * Makes the specified query parameter reactive.
773
+ *
774
+ * @see https://hybridly.dev/api/utils/use-query-parameter.html
775
+ */
776
+ declare function useQueryParameter<ParameterType extends RouteParameter = RouteParameter, Options extends UseQueryParameterOptions<ParameterType, any> = UseQueryParameterOptions<ParameterType, ParameterType>>(name: string, options?: Options): Ref<TransformType<ParameterType, Options>>;
747
777
 
748
778
  /**
749
779
  * Initializes Hybridly's router and context.
@@ -921,4 +951,4 @@ declare const RouterLink: vue.DefineComponent<{
921
951
  preload: boolean | "hover" | "mount";
922
952
  }, {}>;
923
953
 
924
- export { type Action, type AvailableHybridRequestOptions, type BindFilterOptions, type BulkAction, type BulkSelection, type Column, type DefaultFormOptions, type InitializeOptions, type InlineAction, type RecordIdentifier, RouterLink, type SortDirection, type ToggleSortOptions, initializeHybridly, registerHook, setProperty, useBackForward, useBulkSelect, useDialog, useForm, useHistoryState, useProperties, useProperty, useQueryParameters, useRefinements, useRoute, useTable };
954
+ export { type Action, type AvailableHybridRequestOptions, type BindFilterOptions, type BulkAction, type BulkSelection, type Column, type DefaultFormOptions, type InitializeOptions, type InlineAction, type RecordIdentifier, RouterLink, type SortDirection, type ToggleSortOptions, initializeHybridly, registerHook, setProperty, useBackForward, useBulkSelect, useDialog, useForm, useHistoryState, useProperties, useProperty, useQueryParameter, useQueryParameters, useRefinements, useRoute, useTable };
package/dist/index.mjs CHANGED
@@ -940,7 +940,7 @@ function useDialog() {
940
940
  /** Unmounts the dialog. Should be called after its closing animations. */
941
941
  unmount: () => dialogStore.removeComponent(),
942
942
  /** Whether the dialog is shown. */
943
- show: computed(() => dialogStore.state.show.value),
943
+ show: computed({ get: () => dialogStore.state.show.value, set: (v) => !v ? router.dialog.close({ local: true }) : null }),
944
944
  /** Properties of the dialog. */
945
945
  properties: computed(() => state.context.value?.dialog?.properties)
946
946
  };
@@ -1179,15 +1179,19 @@ function useRefinements(properties, refinementsKeys, defaultOptions = {}) {
1179
1179
  };
1180
1180
  }
1181
1181
 
1182
+ const isNavigating = ref(false);
1182
1183
  function useRoute() {
1183
1184
  const current = ref(router.current());
1184
1185
  function matches(name, parameters) {
1185
1186
  return router.matches(toValue(name), parameters);
1186
1187
  }
1188
+ registerHook("before", () => isNavigating.value = true);
1189
+ registerHook("after", () => isNavigating.value = false);
1187
1190
  registerHook("navigated", () => {
1188
1191
  current.value = router.current();
1189
1192
  });
1190
1193
  return {
1194
+ isNavigating: readonly(isNavigating),
1191
1195
  current: readonly(current),
1192
1196
  matches
1193
1197
  };
@@ -1315,7 +1319,7 @@ function useTable(props, key, defaultOptions = {}) {
1315
1319
  /** Deselects records on the current page. */
1316
1320
  deselectPage: () => bulk.deselect(...table.value.records.map((record) => getRecordKey(record))),
1317
1321
  /** Whether all records on the current page are selected. */
1318
- isPageSelected: computed(() => table.value.records.every((record) => bulk.selected(getRecordKey(record)))),
1322
+ isPageSelected: computed(() => table.value.records.length > 0 && table.value.records.every((record) => bulk.selected(getRecordKey(record)))),
1319
1323
  /** Checks if the given record is selected. */
1320
1324
  isSelected: (record) => bulk.selected(getRecordKey(record)),
1321
1325
  /** Whether all records are selected. */
@@ -1411,5 +1415,27 @@ function useQueryParameters() {
1411
1415
  registerHook$1("after", updateState);
1412
1416
  return state;
1413
1417
  }
1418
+ function useQueryParameter(name, options = {}) {
1419
+ const query = useQueryParameters();
1420
+ const transform = (value2) => {
1421
+ if (options.transform === "bool") {
1422
+ return value2 === true || value2 === "true" || value2 === "1" || value2 === "yes";
1423
+ } else if (options.transform === "number") {
1424
+ return Number(value2);
1425
+ } else if (options.transform === "string") {
1426
+ return String(value2);
1427
+ } else if (options.transform === "date") {
1428
+ return new Date(value2);
1429
+ } else if (typeof options.transform === "function") {
1430
+ return options.transform(value2);
1431
+ }
1432
+ return value2;
1433
+ };
1434
+ const value = ref();
1435
+ watch(query, () => {
1436
+ value.value = transform(query[name] ?? toValue(options.defaultValue));
1437
+ }, { deep: true, immediate: true });
1438
+ return value;
1439
+ }
1414
1440
 
1415
- export { RouterLink, initializeHybridly, registerHook, setProperty, useBackForward, useBulkSelect, useDialog, useForm, useHistoryState, useProperties, useProperty, useQueryParameters, useRefinements, useRoute, useTable };
1441
+ export { RouterLink, initializeHybridly, registerHook, setProperty, useBackForward, useBulkSelect, useDialog, useForm, useHistoryState, useProperties, useProperty, useQueryParameter, useQueryParameters, useRefinements, useRoute, useTable };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@hybridly/vue",
3
3
  "type": "module",
4
- "version": "0.7.10",
4
+ "version": "0.7.11",
5
5
  "description": "Vue adapter for Hybridly",
6
6
  "author": "Enzo Innocenzi <enzo@innocenzi.dev>",
7
7
  "license": "MIT",
@@ -49,8 +49,8 @@
49
49
  "lodash.isequal": "^4.5.0",
50
50
  "nprogress": "^0.2.0",
51
51
  "qs": "^6.12.1",
52
- "@hybridly/core": "0.7.10",
53
- "@hybridly/utils": "0.7.10"
52
+ "@hybridly/utils": "0.7.11",
53
+ "@hybridly/core": "0.7.11"
54
54
  },
55
55
  "devDependencies": {
56
56
  "@types/lodash": "^4.17.6",