@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 +91 -10
- package/dist/index.d.ts +54 -7
- package/dist/index.mjs +92 -13
- package/package.json +4 -4
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.
|
|
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
|
-
|
|
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(
|
|
804
|
-
|
|
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
|
-
[
|
|
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(
|
|
839
|
-
const sort =
|
|
890
|
+
async function toggleSort(name, options) {
|
|
891
|
+
const sort = getSort(name);
|
|
840
892
|
if (!sort) {
|
|
841
|
-
console.warn(`[Refinement] Sort "${
|
|
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
|
-
|
|
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: (
|
|
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: (
|
|
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.
|
|
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
|
-
|
|
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(
|
|
796
|
-
|
|
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
|
-
[
|
|
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(
|
|
831
|
-
const sort =
|
|
882
|
+
async function toggleSort(name, options) {
|
|
883
|
+
const sort = getSort(name);
|
|
832
884
|
if (!sort) {
|
|
833
|
-
console.warn(`[Refinement] Sort "${
|
|
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
|
-
|
|
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.
|
|
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.
|
|
48
|
-
"@hybridly/
|
|
49
|
-
"@hybridly/
|
|
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",
|