@hybridly/vue 0.4.0 → 0.4.2

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
@@ -127,7 +127,9 @@ const wrapper = vue.defineComponent({
127
127
  actual?.();
128
128
  vue.nextTick(() => {
129
129
  utils.debug.adapter("vue:render:view", "Calling mounted callbacks.");
130
- onMountedCallbacks.pop()?.();
130
+ while (onMountedCallbacks.length) {
131
+ onMountedCallbacks.shift()?.();
132
+ }
131
133
  });
132
134
  };
133
135
  return vue.h(state.view.value, {
@@ -288,7 +290,7 @@ async function initializeHybridly(options = {}) {
288
290
  routing: resolved.routing,
289
291
  adapter: {
290
292
  resolveComponent: resolve,
291
- onWaitingForMount: (callback) => {
293
+ executeOnMounted: (callback) => {
292
294
  onMountedCallbacks.push(callback);
293
295
  },
294
296
  onDialogClose: async () => {
@@ -391,6 +393,7 @@ const RouterLink = vue.defineComponent({
391
393
  setup(_, { slots, attrs }) {
392
394
  return (props) => {
393
395
  let data = props.data ?? {};
396
+ const preloads = props.preload ?? false;
394
397
  const url = core.makeUrl(props.href ?? "");
395
398
  const method = props.method?.toUpperCase() ?? "GET";
396
399
  const as = typeof props.as === "object" ? props.as : props.as?.toLowerCase() ?? "a";
@@ -413,6 +416,24 @@ Please specify a more appropriate element using the "as" attribute. For example:
413
416
  ...attrs,
414
417
  ...as === "a" ? { href: url } : {},
415
418
  ...props.disabled ? { disabled: props.disabled } : {},
419
+ onMouseenter: () => {
420
+ if (!preloads) {
421
+ return;
422
+ }
423
+ if (props.external) {
424
+ return;
425
+ }
426
+ if (props.disabled) {
427
+ return;
428
+ }
429
+ if (method !== "GET") {
430
+ return;
431
+ }
432
+ core.router.preload(url, {
433
+ data,
434
+ ...props.options
435
+ });
436
+ },
416
437
  onClick: (event) => {
417
438
  if (props.external) {
418
439
  return;
@@ -469,6 +490,10 @@ Please specify a more appropriate element using the "as" attribute. For example:
469
490
  type: String,
470
491
  required: false,
471
492
  default: void 0
493
+ },
494
+ preload: {
495
+ type: Boolean,
496
+ default: false
472
497
  }
473
498
  }
474
499
  });
@@ -518,6 +543,12 @@ function useProperties() {
518
543
  function useProperty(path) {
519
544
  return vue.computed(() => dotDiver.getByPath(state.context.value?.view.properties, path));
520
545
  }
546
+ function setProperty(path, value) {
547
+ if (!state.context.value?.view.properties) {
548
+ return;
549
+ }
550
+ dotDiver.setByPath(state.context.value.view.properties, path, vue.toValue(value));
551
+ }
521
552
 
522
553
  function useContext() {
523
554
  return vue.computed(() => state.context.value);
@@ -770,6 +801,16 @@ function useRefinements(properties, refinementsKeys, defaultOptions = {}) {
770
801
  const refinements = vue.computed(() => properties[refinementsKeys]);
771
802
  const sortsKey = vue.computed(() => refinements.value.keys.sorts);
772
803
  const filtersKey = vue.computed(() => refinements.value.keys.filters);
804
+ defaultOptions = {
805
+ replace: false,
806
+ ...defaultOptions
807
+ };
808
+ function getSort(name) {
809
+ return refinements.value.sorts.find((sort) => sort.name === name);
810
+ }
811
+ function getFilter(name) {
812
+ return refinements.value.filters.find((sort) => sort.name === name);
813
+ }
773
814
  async function reset(options = {}) {
774
815
  return await core.router.reload({
775
816
  ...defaultOptions,
@@ -800,16 +841,21 @@ function useRefinements(properties, refinementsKeys, defaultOptions = {}) {
800
841
  }
801
842
  });
802
843
  }
803
- async function applyFilter(filter, value, options = {}) {
804
- if (!refinements.value.filters.find(({ name }) => name === filter)) {
844
+ async function applyFilter(name, value, options = {}) {
845
+ const filter = getFilter(name);
846
+ if (!filter) {
847
+ console.warn(`[Refinement] Filter "${name} does not exist."`);
805
848
  return;
806
849
  }
850
+ if (["", null].includes(value) || value === filter.default) {
851
+ value = void 0;
852
+ }
807
853
  return await core.router.reload({
808
854
  ...defaultOptions,
809
855
  ...options,
810
856
  data: {
811
857
  [filtersKey.value]: {
812
- [filter]: value === "" ? void 0 : value
858
+ [name]: value
813
859
  }
814
860
  }
815
861
  });
@@ -829,16 +875,22 @@ function useRefinements(properties, refinementsKeys, defaultOptions = {}) {
829
875
  function currentFilters() {
830
876
  return refinements.value.filters.filter(({ is_active }) => is_active);
831
877
  }
832
- function isSorting() {
878
+ function isSorting(name) {
879
+ if (name) {
880
+ return currentSorts().some((sort) => sort.name === name);
881
+ }
833
882
  return currentSorts().length !== 0;
834
883
  }
835
- function isFiltering() {
884
+ function isFiltering(name) {
885
+ if (name) {
886
+ return currentFilters().some((filter) => filter.name === name);
887
+ }
836
888
  return currentFilters().length !== 0;
837
889
  }
838
- async function toggleSort(sortName, options) {
839
- const sort = refinements.value.sorts.find(({ name }) => name === sortName);
890
+ async function toggleSort(name, options) {
891
+ const sort = getSort(name);
840
892
  if (!sort) {
841
- console.warn(`[Refinement] Sort "${sortName} does not exist."`);
893
+ console.warn(`[Refinement] Sort "${name} does not exist."`);
842
894
  return;
843
895
  }
844
896
  const next = options?.direction ? sort[options?.direction] : sort.next;
@@ -850,9 +902,22 @@ function useRefinements(properties, refinementsKeys, defaultOptions = {}) {
850
902
  }
851
903
  });
852
904
  }
905
+ function bindFilter(name, options = {}) {
906
+ const transform = options?.transformValue ?? ((value) => value);
907
+ const watchFn = options?.watch ?? vue.watch;
908
+ const _ref = vue.ref(transform(refinements.value.filters.find((f) => f.name === name)?.value));
909
+ vue.watch(() => refinements.value.filters.find((f) => f.name === name), (filter) => {
910
+ _ref.value = transform(filter?.value);
911
+ }, { deep: true });
912
+ watchFn(_ref, (value) => applyFilter(name, transform(value), options));
913
+ return _ref;
914
+ }
853
915
  return {
916
+ bindFilter,
854
917
  filters: toReactive(refinements.value.filters),
855
918
  sorts: toReactive(refinements.value.sorts),
919
+ getFilter,
920
+ getSort,
856
921
  reset,
857
922
  toggleSort,
858
923
  isSorting,
@@ -866,6 +931,20 @@ function useRefinements(properties, refinementsKeys, defaultOptions = {}) {
866
931
  };
867
932
  }
868
933
 
934
+ function useRoute() {
935
+ const current = vue.ref(hybridly.router.current());
936
+ function matches(name, parameters) {
937
+ return hybridly.router.matches(vue.toValue(name), parameters);
938
+ }
939
+ registerHook("navigated", () => {
940
+ current.value = hybridly.router.current();
941
+ });
942
+ return {
943
+ current: vue.readonly(current),
944
+ matches
945
+ };
946
+ }
947
+
869
948
  exports.can = core.can;
870
949
  exports.route = core.route;
871
950
  exports.router = core.router;
@@ -874,6 +953,7 @@ exports.defineLayout = defineLayout;
874
953
  exports.defineLayoutProperties = defineLayoutProperties;
875
954
  exports.initializeHybridly = initializeHybridly;
876
955
  exports.registerHook = registerHook;
956
+ exports.setProperty = setProperty;
877
957
  exports.useBackForward = useBackForward;
878
958
  exports.useContext = useContext;
879
959
  exports.useDialog = useDialog;
@@ -883,3 +963,4 @@ exports.usePaginator = usePaginator;
883
963
  exports.useProperties = useProperties;
884
964
  exports.useProperty = useProperty;
885
965
  exports.useRefinements = useRefinements;
966
+ exports.useRoute = useRoute;
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as vue from 'vue';
2
- import { App, Plugin as Plugin$2, h, PropType, ComputedRef, DeepReadonly } from 'vue';
2
+ import { App, Plugin as Plugin$2, h, PropType, ComputedRef, DeepReadonly, Ref, MaybeRefOrGetter } from 'vue';
3
3
  import * as _hybridly_core from '@hybridly/core';
4
4
  import { RouterContextOptions, Plugin as Plugin$1, RouterContext, Method as Method$1, HybridRequestOptions as HybridRequestOptions$1, UrlResolvable as UrlResolvable$1, registerHook as registerHook$1 } from '@hybridly/core';
5
5
  export { can, route, router } from '@hybridly/core';
@@ -85,6 +85,10 @@ declare const RouterLink: vue.DefineComponent<{
85
85
  required: false;
86
86
  default: undefined;
87
87
  };
88
+ preload: {
89
+ type: BooleanConstructor;
90
+ default: boolean;
91
+ };
88
92
  }, (props: _vue_shared.LooseRequired<{
89
93
  readonly data: RequestData;
90
94
  readonly method: "delete" | Method$1 | "get" | "post" | "put" | "patch";
@@ -92,6 +96,7 @@ declare const RouterLink: vue.DefineComponent<{
92
96
  readonly as: string | Record<string, any>;
93
97
  readonly external: boolean;
94
98
  readonly disabled: boolean;
99
+ readonly preload: boolean;
95
100
  readonly text?: string | undefined;
96
101
  readonly href?: string | undefined;
97
102
  } & {}>) => vue.VNode<vue.RendererNode, vue.RendererElement, {
@@ -131,6 +136,10 @@ declare const RouterLink: vue.DefineComponent<{
131
136
  required: false;
132
137
  default: undefined;
133
138
  };
139
+ preload: {
140
+ type: BooleanConstructor;
141
+ default: boolean;
142
+ };
134
143
  }>>, {
135
144
  data: RequestData;
136
145
  text: string;
@@ -140,12 +149,18 @@ declare const RouterLink: vue.DefineComponent<{
140
149
  as: string | Record<string, any>;
141
150
  external: boolean;
142
151
  disabled: boolean;
152
+ preload: boolean;
143
153
  }, {}>;
144
154
 
145
155
  /** Accesses all current properties. */
146
156
  declare function useProperties<T extends object, Global extends GlobalHybridlyProperties>(): vue.DeepReadonly<vue.UnwrapNestedRefs<T & Global>>;
147
157
  /** Accesses a property with a dot notation. */
148
158
  declare function useProperty<Override = never, T extends SearchableObject = GlobalHybridlyProperties, P extends Path<T> & string = Path<T> & string, ReturnType = [Override] extends [never] ? PathValue<T, P> : Override>(path: [Override] extends [never] ? P : string): ComputedRef<ReturnType>;
159
+ /**
160
+ * Sets the property at the given path to the given value.
161
+ * Note: this helper is experimental and may change in the future.
162
+ */
163
+ declare function setProperty<Override = never, T extends SearchableObject = GlobalHybridlyProperties, P extends Path<T> & string = Path<T> & string, ValueType = [Override] extends [never] ? PathValue<T, P> : Override>(path: [Override] extends [never] ? P : string, value: ValueType): void;
149
164
 
150
165
  type UrlResolvable = string | URL | Location;
151
166
  type UrlTransformable = BaseUrlTransformable | ((string: URL) => BaseUrlTransformable);
@@ -223,6 +238,10 @@ interface Hooks extends RequestHooks {
223
238
  * Called when a component has been navigated to.
224
239
  */
225
240
  navigated: (options: NavigationOptions, context: InternalRouterContext) => MaybePromise<any>;
241
+ /**
242
+ * Called when a component has been navigated to and was mounted by the adapter.
243
+ */
244
+ mounted: (context: InternalRouterContext) => MaybePromise<any>;
226
245
  }
227
246
 
228
247
  interface RoutingConfiguration {
@@ -405,6 +424,8 @@ interface InternalRouterContext {
405
424
  routing?: RoutingConfiguration;
406
425
  /** Whether to display response error modals. */
407
426
  responseErrorModals?: boolean;
427
+ /** Cache of preload requests. */
428
+ preloadCache: Map<string, AxiosResponse>;
408
429
  }
409
430
  /** Adapter-specific functions. */
410
431
  interface Adapter {
@@ -417,7 +438,7 @@ interface Adapter {
417
438
  /** Called when a dialog is closed. */
418
439
  onDialogClose?: (context: InternalRouterContext) => void;
419
440
  /** Called when Hybridly is waiting for a component to be mounted. The given callback should be executed after the view component is mounted. */
420
- onWaitingForMount: (callback: Function) => void;
441
+ executeOnMounted: (callback: Function) => void;
421
442
  }
422
443
  interface ResolvedAdapter extends Adapter {
423
444
  updateRoutingConfiguration: (routing?: RoutingConfiguration) => void;
@@ -625,6 +646,11 @@ type AvailableHybridRequestOptions = Omit<HybridRequestOptions$1, 'url' | 'data'
625
646
  interface ToggleSortOptions extends AvailableHybridRequestOptions {
626
647
  direction?: SortDirection;
627
648
  }
649
+ interface BindFilterOptions<T> extends AvailableHybridRequestOptions {
650
+ transformValue?: (value?: T) => any;
651
+ /** If specified, this callback will watch the ref and apply */
652
+ watch?: (ref: Ref<T>, cb: any) => void;
653
+ }
628
654
  declare global {
629
655
  interface FilterRefinement {
630
656
  /**
@@ -655,6 +681,10 @@ declare global {
655
681
  * Whether this filter is hidden.
656
682
  */
657
683
  hidden: boolean;
684
+ /**
685
+ * The default value of the filter.
686
+ */
687
+ default: any;
658
688
  }
659
689
  interface SortRefinement {
660
690
  /**
@@ -729,6 +759,10 @@ declare global {
729
759
  declare function useRefinements<Properties extends object, RefinementsKey extends {
730
760
  [K in keyof Properties]: Properties[K] extends Refinements ? K : never;
731
761
  }[keyof Properties]>(properties: Properties, refinementsKeys: RefinementsKey, defaultOptions?: AvailableHybridRequestOptions): {
762
+ /**
763
+ * Binds a named filter to a ref, applying filters when it changes and updating the ref accordingly.
764
+ */
765
+ bindFilter: <T = any>(name: string, options?: BindFilterOptions<T>) => Ref<T>;
732
766
  /**
733
767
  * Available filters.
734
768
  */
@@ -737,6 +771,14 @@ declare function useRefinements<Properties extends object, RefinementsKey extend
737
771
  * Available sorts.
738
772
  */
739
773
  sorts: SortRefinement[];
774
+ /**
775
+ * Gets a filter by name.
776
+ */
777
+ getFilter: (name: string) => FilterRefinement | undefined;
778
+ /**
779
+ * Gets a sort by name.
780
+ */
781
+ getSort: (name: string) => SortRefinement | undefined;
740
782
  /**
741
783
  * Resets all filters and sorts.
742
784
  */
@@ -744,15 +786,15 @@ declare function useRefinements<Properties extends object, RefinementsKey extend
744
786
  /**
745
787
  * Toggles the specified sort.
746
788
  */
747
- toggleSort: (sortName: string, options?: ToggleSortOptions) => Promise<_hybridly_core.NavigationResponse | undefined>;
789
+ toggleSort: (name: string, options?: ToggleSortOptions) => Promise<_hybridly_core.NavigationResponse | undefined>;
748
790
  /**
749
791
  * Whether a sort is active.
750
792
  */
751
- isSorting: () => boolean;
793
+ isSorting: (name?: string) => boolean;
752
794
  /**
753
795
  * Whether a filter is active.
754
796
  */
755
- isFiltering: () => boolean;
797
+ isFiltering: (name?: string) => boolean;
756
798
  /**
757
799
  * The current sorts.
758
800
  */
@@ -776,7 +818,12 @@ declare function useRefinements<Properties extends object, RefinementsKey extend
776
818
  /**
777
819
  * Applies the given filter.
778
820
  */
779
- applyFilter: (filter: string, value: any, options?: AvailableHybridRequestOptions) => Promise<_hybridly_core.NavigationResponse | undefined>;
821
+ applyFilter: (name: string, value: any, options?: AvailableHybridRequestOptions) => Promise<_hybridly_core.NavigationResponse | undefined>;
822
+ };
823
+
824
+ declare function useRoute(): {
825
+ current: Readonly<vue.Ref<string | undefined>>;
826
+ matches: <T extends string>(name: MaybeRefOrGetter<T>, parameters?: Record<string, any> | undefined) => boolean;
780
827
  };
781
828
 
782
- export { Layout, RouterLink, defineLayout, defineLayoutProperties, initializeHybridly, registerHook, useBackForward, useContext, useDialog, useForm, useHistoryState, usePaginator, useProperties, useProperty, useRefinements };
829
+ export { Layout, RouterLink, defineLayout, defineLayoutProperties, initializeHybridly, registerHook, setProperty, useBackForward, useContext, useDialog, useForm, useHistoryState, usePaginator, useProperties, useProperty, useRefinements, useRoute };
package/dist/index.mjs CHANGED
@@ -1,11 +1,11 @@
1
- import { shallowRef, ref, unref, triggerRef, defineComponent, toRaw, h, nextTick, createApp, isRef, reactive, readonly, computed, watch, getCurrentInstance, onUnmounted } from 'vue';
1
+ import { shallowRef, ref, unref, triggerRef, defineComponent, toRaw, h, nextTick, createApp, isRef, reactive, readonly, computed, toValue, watch, getCurrentInstance, onUnmounted } from 'vue';
2
2
  import { registerHook as registerHook$1, createRouter, makeUrl, router } from '@hybridly/core';
3
3
  export { can, route, router } from '@hybridly/core';
4
4
  import { debug, random, showPageComponentErrorModal, merge, clone, unsetPropertyAtPath, setValueAtPath } from '@hybridly/utils';
5
5
  import { progress } from '@hybridly/progress-plugin';
6
6
  import { setupDevtoolsPlugin } from '@vue/devtools-api';
7
7
  import qs from 'qs';
8
- import { getByPath } from '@clickbar/dot-diver';
8
+ import { getByPath, setByPath } from '@clickbar/dot-diver';
9
9
  import isEqual from 'lodash.isequal';
10
10
  import { router as router$1 } from 'hybridly';
11
11
 
@@ -119,7 +119,9 @@ const wrapper = defineComponent({
119
119
  actual?.();
120
120
  nextTick(() => {
121
121
  debug.adapter("vue:render:view", "Calling mounted callbacks.");
122
- onMountedCallbacks.pop()?.();
122
+ while (onMountedCallbacks.length) {
123
+ onMountedCallbacks.shift()?.();
124
+ }
123
125
  });
124
126
  };
125
127
  return h(state.view.value, {
@@ -280,7 +282,7 @@ async function initializeHybridly(options = {}) {
280
282
  routing: resolved.routing,
281
283
  adapter: {
282
284
  resolveComponent: resolve,
283
- onWaitingForMount: (callback) => {
285
+ executeOnMounted: (callback) => {
284
286
  onMountedCallbacks.push(callback);
285
287
  },
286
288
  onDialogClose: async () => {
@@ -383,6 +385,7 @@ const RouterLink = defineComponent({
383
385
  setup(_, { slots, attrs }) {
384
386
  return (props) => {
385
387
  let data = props.data ?? {};
388
+ const preloads = props.preload ?? false;
386
389
  const url = makeUrl(props.href ?? "");
387
390
  const method = props.method?.toUpperCase() ?? "GET";
388
391
  const as = typeof props.as === "object" ? props.as : props.as?.toLowerCase() ?? "a";
@@ -405,6 +408,24 @@ Please specify a more appropriate element using the "as" attribute. For example:
405
408
  ...attrs,
406
409
  ...as === "a" ? { href: url } : {},
407
410
  ...props.disabled ? { disabled: props.disabled } : {},
411
+ onMouseenter: () => {
412
+ if (!preloads) {
413
+ return;
414
+ }
415
+ if (props.external) {
416
+ return;
417
+ }
418
+ if (props.disabled) {
419
+ return;
420
+ }
421
+ if (method !== "GET") {
422
+ return;
423
+ }
424
+ router.preload(url, {
425
+ data,
426
+ ...props.options
427
+ });
428
+ },
408
429
  onClick: (event) => {
409
430
  if (props.external) {
410
431
  return;
@@ -461,6 +482,10 @@ Please specify a more appropriate element using the "as" attribute. For example:
461
482
  type: String,
462
483
  required: false,
463
484
  default: void 0
485
+ },
486
+ preload: {
487
+ type: Boolean,
488
+ default: false
464
489
  }
465
490
  }
466
491
  });
@@ -510,6 +535,12 @@ function useProperties() {
510
535
  function useProperty(path) {
511
536
  return computed(() => getByPath(state.context.value?.view.properties, path));
512
537
  }
538
+ function setProperty(path, value) {
539
+ if (!state.context.value?.view.properties) {
540
+ return;
541
+ }
542
+ setByPath(state.context.value.view.properties, path, toValue(value));
543
+ }
513
544
 
514
545
  function useContext() {
515
546
  return computed(() => state.context.value);
@@ -762,6 +793,16 @@ function useRefinements(properties, refinementsKeys, defaultOptions = {}) {
762
793
  const refinements = computed(() => properties[refinementsKeys]);
763
794
  const sortsKey = computed(() => refinements.value.keys.sorts);
764
795
  const filtersKey = computed(() => refinements.value.keys.filters);
796
+ defaultOptions = {
797
+ replace: false,
798
+ ...defaultOptions
799
+ };
800
+ function getSort(name) {
801
+ return refinements.value.sorts.find((sort) => sort.name === name);
802
+ }
803
+ function getFilter(name) {
804
+ return refinements.value.filters.find((sort) => sort.name === name);
805
+ }
765
806
  async function reset(options = {}) {
766
807
  return await router.reload({
767
808
  ...defaultOptions,
@@ -792,16 +833,21 @@ function useRefinements(properties, refinementsKeys, defaultOptions = {}) {
792
833
  }
793
834
  });
794
835
  }
795
- async function applyFilter(filter, value, options = {}) {
796
- if (!refinements.value.filters.find(({ name }) => name === filter)) {
836
+ async function applyFilter(name, value, options = {}) {
837
+ const filter = getFilter(name);
838
+ if (!filter) {
839
+ console.warn(`[Refinement] Filter "${name} does not exist."`);
797
840
  return;
798
841
  }
842
+ if (["", null].includes(value) || value === filter.default) {
843
+ value = void 0;
844
+ }
799
845
  return await router.reload({
800
846
  ...defaultOptions,
801
847
  ...options,
802
848
  data: {
803
849
  [filtersKey.value]: {
804
- [filter]: value === "" ? void 0 : value
850
+ [name]: value
805
851
  }
806
852
  }
807
853
  });
@@ -821,16 +867,22 @@ function useRefinements(properties, refinementsKeys, defaultOptions = {}) {
821
867
  function currentFilters() {
822
868
  return refinements.value.filters.filter(({ is_active }) => is_active);
823
869
  }
824
- function isSorting() {
870
+ function isSorting(name) {
871
+ if (name) {
872
+ return currentSorts().some((sort) => sort.name === name);
873
+ }
825
874
  return currentSorts().length !== 0;
826
875
  }
827
- function isFiltering() {
876
+ function isFiltering(name) {
877
+ if (name) {
878
+ return currentFilters().some((filter) => filter.name === name);
879
+ }
828
880
  return currentFilters().length !== 0;
829
881
  }
830
- async function toggleSort(sortName, options) {
831
- const sort = refinements.value.sorts.find(({ name }) => name === sortName);
882
+ async function toggleSort(name, options) {
883
+ const sort = getSort(name);
832
884
  if (!sort) {
833
- console.warn(`[Refinement] Sort "${sortName} does not exist."`);
885
+ console.warn(`[Refinement] Sort "${name} does not exist."`);
834
886
  return;
835
887
  }
836
888
  const next = options?.direction ? sort[options?.direction] : sort.next;
@@ -842,9 +894,22 @@ function useRefinements(properties, refinementsKeys, defaultOptions = {}) {
842
894
  }
843
895
  });
844
896
  }
897
+ function bindFilter(name, options = {}) {
898
+ const transform = options?.transformValue ?? ((value) => value);
899
+ const watchFn = options?.watch ?? watch;
900
+ const _ref = ref(transform(refinements.value.filters.find((f) => f.name === name)?.value));
901
+ watch(() => refinements.value.filters.find((f) => f.name === name), (filter) => {
902
+ _ref.value = transform(filter?.value);
903
+ }, { deep: true });
904
+ watchFn(_ref, (value) => applyFilter(name, transform(value), options));
905
+ return _ref;
906
+ }
845
907
  return {
908
+ bindFilter,
846
909
  filters: toReactive(refinements.value.filters),
847
910
  sorts: toReactive(refinements.value.sorts),
911
+ getFilter,
912
+ getSort,
848
913
  reset,
849
914
  toggleSort,
850
915
  isSorting,
@@ -858,4 +923,18 @@ function useRefinements(properties, refinementsKeys, defaultOptions = {}) {
858
923
  };
859
924
  }
860
925
 
861
- export { RouterLink, defineLayout, defineLayoutProperties, initializeHybridly, registerHook, useBackForward, useContext, useDialog, useForm, useHistoryState, usePaginator, useProperties, useProperty, useRefinements };
926
+ function useRoute() {
927
+ const current = ref(router$1.current());
928
+ function matches(name, parameters) {
929
+ return router$1.matches(toValue(name), parameters);
930
+ }
931
+ registerHook("navigated", () => {
932
+ current.value = router$1.current();
933
+ });
934
+ return {
935
+ current: readonly(current),
936
+ matches
937
+ };
938
+ }
939
+
940
+ export { RouterLink, defineLayout, defineLayoutProperties, initializeHybridly, registerHook, setProperty, useBackForward, useContext, useDialog, useForm, useHistoryState, usePaginator, useProperties, useProperty, useRefinements, useRoute };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hybridly/vue",
3
- "version": "0.4.0",
3
+ "version": "0.4.2",
4
4
  "description": "Vue adapter for Hybridly",
5
5
  "keywords": [
6
6
  "hybridly",
@@ -44,9 +44,9 @@
44
44
  "lodash.isequal": "^4.5.0",
45
45
  "nprogress": "^0.2.0",
46
46
  "qs": "^6.11.2",
47
- "@hybridly/core": "0.4.0",
48
- "@hybridly/utils": "0.4.0",
49
- "@hybridly/progress-plugin": "0.4.0"
47
+ "@hybridly/core": "0.4.2",
48
+ "@hybridly/progress-plugin": "0.4.2",
49
+ "@hybridly/utils": "0.4.2"
50
50
  },
51
51
  "devDependencies": {
52
52
  "@types/lodash": "^4.14.195",