@hybridly/vue 0.7.13 → 0.7.15

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
@@ -200,7 +200,10 @@ const wrapper = vue.defineComponent({
200
200
  function renderLayout(view) {
201
201
  utils.debug.adapter("vue:render:layout", "Rendering layout.");
202
202
  if (typeof state.view.value?.layout === "function") {
203
- return state.view.value.layout(vue.h, view, renderDialog());
203
+ return state.view.value.layout(vue.h, view, renderDialog(), {
204
+ ...state.view.value?.properties ?? {},
205
+ ...state.properties.value
206
+ });
204
207
  }
205
208
  if (Array.isArray(state.view.value?.layout)) {
206
209
  const layoutsAndView = state.view.value.layout.concat(view).reverse().reduce((child, layout) => {
@@ -596,6 +599,9 @@ Please specify a more appropriate element using the "as" attribute. For example:
596
599
  ...props.disabled ? { disabled: props.disabled } : {},
597
600
  onMouseenter: () => performPreload("hover"),
598
601
  onClick: (event) => {
602
+ if (props.disabled) {
603
+ return;
604
+ }
599
605
  if (props.external) {
600
606
  return;
601
607
  }
@@ -603,9 +609,6 @@ Please specify a more appropriate element using the "as" attribute. For example:
603
609
  return;
604
610
  }
605
611
  event.preventDefault();
606
- if (props.disabled) {
607
- return;
608
- }
609
612
  core.router.navigate({
610
613
  url,
611
614
  data,
@@ -1000,7 +1003,7 @@ function useRefinements(properties, refinementsKeys, defaultOptions = {}) {
1000
1003
  async function applyFilter(name, value, options = {}) {
1001
1004
  const filter = getFilter(name);
1002
1005
  if (!filter) {
1003
- console.warn(`[Refinement] Filter "${name} does not exist."`);
1006
+ console.warn(`[Refinement] Filter "${name}" does not exist.`);
1004
1007
  return;
1005
1008
  }
1006
1009
  if (["", null].includes(value) || value === filter.default) {
@@ -1046,7 +1049,7 @@ function useRefinements(properties, refinementsKeys, defaultOptions = {}) {
1046
1049
  async function toggleSort(name, options) {
1047
1050
  const sort = getSort(name);
1048
1051
  if (!sort) {
1049
- console.warn(`[Refinement] Sort "${name} does not exist."`);
1052
+ console.warn(`[Refinement] Sort "${name}" does not exist.`);
1050
1053
  return;
1051
1054
  }
1052
1055
  const next = options?.direction ? sort[options?.direction] : sort.next;
@@ -1245,6 +1248,20 @@ function useBulkSelect() {
1245
1248
  const allSelected = vue.computed(() => {
1246
1249
  return selection.value.all && selection.value.except.size === 0;
1247
1250
  });
1251
+ function bindCheckbox(key) {
1252
+ return {
1253
+ onChange: (event) => {
1254
+ const target = event.target;
1255
+ if (target.checked) {
1256
+ select(target.value);
1257
+ } else {
1258
+ deselect(target.value);
1259
+ }
1260
+ },
1261
+ checked: selected(key),
1262
+ value: key
1263
+ };
1264
+ }
1248
1265
  return {
1249
1266
  allSelected,
1250
1267
  selectAll,
@@ -1253,20 +1270,70 @@ function useBulkSelect() {
1253
1270
  deselect,
1254
1271
  toggle,
1255
1272
  selected,
1256
- selection
1273
+ selection,
1274
+ bindCheckbox
1257
1275
  };
1258
1276
  }
1259
1277
 
1278
+ function useQueryParameters() {
1279
+ const state = vue.reactive({});
1280
+ function updateState() {
1281
+ const params = new URLSearchParams(window.location.search);
1282
+ const unusedKeys = new Set(Object.keys(state));
1283
+ for (const key of params.keys()) {
1284
+ const paramsForKey = params.getAll(key);
1285
+ state[key] = paramsForKey.length > 1 ? paramsForKey : params.get(key) || "";
1286
+ unusedKeys.delete(key);
1287
+ }
1288
+ Array.from(unusedKeys).forEach((key) => delete state[key]);
1289
+ }
1290
+ updateState();
1291
+ core.registerHook("after", updateState);
1292
+ return state;
1293
+ }
1294
+ function useQueryParameter(name, options = {}) {
1295
+ const query = useQueryParameters();
1296
+ const transform = (value2) => {
1297
+ if (options.transform === "bool") {
1298
+ return value2 === true || value2 === "true" || value2 === "1" || value2 === "yes";
1299
+ } else if (options.transform === "number") {
1300
+ return Number(value2);
1301
+ } else if (options.transform === "string") {
1302
+ return String(value2);
1303
+ } else if (options.transform === "date") {
1304
+ return new Date(value2);
1305
+ } else if (typeof options.transform === "function") {
1306
+ return options.transform(value2);
1307
+ }
1308
+ return value2;
1309
+ };
1310
+ const value = vue.ref();
1311
+ vue.watch(query, () => {
1312
+ value.value = transform(query[name] ?? vue.toValue(options.defaultValue));
1313
+ }, { deep: true, immediate: true });
1314
+ return value;
1315
+ }
1316
+
1260
1317
  function useTable(props, key, defaultOptions = {}) {
1261
1318
  const table = vue.computed(() => props[key]);
1262
1319
  const bulk = useBulkSelect();
1263
1320
  const refinements = useRefinements(toReactive(table), "refinements", defaultOptions);
1321
+ function getAdditionnalData() {
1322
+ const data = {};
1323
+ if (defaultOptions?.includeQueryParameters !== false) {
1324
+ Object.assign(data, structuredClone(vue.toRaw(useQueryParameters())));
1325
+ }
1326
+ if (defaultOptions?.data) {
1327
+ Object.assign(data, defaultOptions.data);
1328
+ }
1329
+ return data;
1330
+ }
1264
1331
  function getRecordKey(record) {
1265
1332
  if (typeof record !== "object") {
1266
1333
  return record;
1267
1334
  }
1268
1335
  if (Reflect.has(record, "__hybridId")) {
1269
- return Reflect.get(record, "__hybridId").value;
1336
+ return Reflect.get(record, "__hybridId");
1270
1337
  }
1271
1338
  return Reflect.get(record, table.value.keyName).value;
1272
1339
  }
@@ -1279,6 +1346,7 @@ function useTable(props, key, defaultOptions = {}) {
1279
1346
  url: core.route(table.value.endpoint),
1280
1347
  preserveState: true,
1281
1348
  data: {
1349
+ ...getAdditionnalData(),
1282
1350
  type: "action:inline",
1283
1351
  action: getActionName(action),
1284
1352
  tableId: table.value.id,
@@ -1299,6 +1367,7 @@ function useTable(props, key, defaultOptions = {}) {
1299
1367
  url: core.route(table.value.endpoint),
1300
1368
  preserveState: true,
1301
1369
  data: {
1370
+ ...getAdditionnalData(),
1302
1371
  type: "action:bulk",
1303
1372
  action: actionName,
1304
1373
  tableId: table.value.id,
@@ -1333,6 +1402,8 @@ function useTable(props, key, defaultOptions = {}) {
1333
1402
  allSelected: bulk.allSelected,
1334
1403
  /** The current record selection. */
1335
1404
  selection: bulk.selection,
1405
+ /** Binds a checkbox to its selection state. */
1406
+ bindCheckbox: (key2) => bulk.bindCheckbox(key2),
1336
1407
  /** Toggles selection for the given record. */
1337
1408
  toggle: (record) => bulk.toggle(getRecordKey(record)),
1338
1409
  /** Selects selection for the given record. */
@@ -1406,45 +1477,6 @@ function useTable(props, key, defaultOptions = {}) {
1406
1477
  });
1407
1478
  }
1408
1479
 
1409
- function useQueryParameters() {
1410
- const state = vue.reactive({});
1411
- function updateState() {
1412
- const params = new URLSearchParams(window.location.search);
1413
- const unusedKeys = new Set(Object.keys(state));
1414
- for (const key of params.keys()) {
1415
- const paramsForKey = params.getAll(key);
1416
- state[key] = paramsForKey.length > 1 ? paramsForKey : params.get(key) || "";
1417
- unusedKeys.delete(key);
1418
- }
1419
- Array.from(unusedKeys).forEach((key) => delete state[key]);
1420
- }
1421
- updateState();
1422
- core.registerHook("after", updateState);
1423
- return state;
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
- }
1447
-
1448
1480
  exports.can = core.can;
1449
1481
  exports.route = core.route;
1450
1482
  exports.router = core.router;
package/dist/index.d.cts CHANGED
@@ -4,9 +4,9 @@ import * as _hybridly_core from '@hybridly/core';
4
4
  import { HybridRequestOptions, UrlResolvable, RouterContext, registerHook as registerHook$1, RouteName, RouteParameters, RouterContextOptions, Plugin, Method } from '@hybridly/core';
5
5
  export { can, route, router } from '@hybridly/core';
6
6
  import { Axios } from 'axios';
7
+ import * as _vue_shared from '@vue/shared';
7
8
  import { SearchableObject, Path, PathValue } from '@clickbar/dot-diver';
8
9
  import { FormDataConvertible, RequestData } from '@hybridly/utils';
9
- import * as _vue_shared from '@vue/shared';
10
10
 
11
11
  interface ProgressOptions {
12
12
  /**
@@ -94,20 +94,20 @@ declare function useForm<T extends SearchableObject, P extends Path<T> & string
94
94
  progress: {
95
95
  readonly event: {
96
96
  readonly loaded: number;
97
- readonly total?: number;
98
- readonly progress?: number;
97
+ readonly total?: number | undefined;
98
+ readonly progress?: number | undefined;
99
99
  readonly bytes: number;
100
- readonly rate?: number;
101
- readonly estimated?: number;
102
- readonly upload?: boolean;
103
- readonly download?: boolean;
100
+ readonly rate?: number | undefined;
101
+ readonly estimated?: number | undefined;
102
+ readonly upload?: boolean | undefined;
103
+ readonly download?: boolean | undefined;
104
104
  readonly event?: any;
105
105
  readonly lengthComputable: boolean;
106
106
  };
107
107
  readonly percentage: Readonly<number>;
108
108
  } | undefined;
109
109
  isDirty: boolean;
110
- errors: DeepReadonly<vue.UnwrapRef<Errors<T>>>;
110
+ errors: vue.UnwrapRef<DeepReadonly<[Errors<T>] extends [vue.Ref<any, any>] ? _vue_shared.IfAny<vue.Ref<any, any> & Errors<T>, vue.Ref<vue.Ref<any, any> & Errors<T>, vue.Ref<any, any> & Errors<T>>, vue.Ref<any, any> & Errors<T>> : vue.Ref<vue.UnwrapRef<Errors<T>>, Errors<T> | vue.UnwrapRef<Errors<T>>>>>;
111
111
  processing: boolean;
112
112
  successful: boolean;
113
113
  failed: boolean;
@@ -119,7 +119,7 @@ declare function useForm<T extends SearchableObject, P extends Path<T> & string
119
119
  * Returns a ref with a value saved in the history state through Hybridly.
120
120
  * The state is linked to a specific browser history entry.
121
121
  */
122
- declare function useHistoryState<T = any>(key: string, initial: T): vue.Ref<vue.UnwrapRef<T>>;
122
+ declare function useHistoryState<T = any>(key: string, initial: T): [T] extends [vue.Ref<any, any>] ? _vue_shared.IfAny<T, vue.Ref<T, T>, T> : vue.Ref<vue.UnwrapRef<T>, T | vue.UnwrapRef<T>>;
123
123
 
124
124
  type BackForwardCallback = (context: RouterContext) => void;
125
125
  interface UseBackForwardOptions {
@@ -172,10 +172,10 @@ interface PaginatorLink {
172
172
  interface CursorPaginatorMeta {
173
173
  path: string;
174
174
  per_page: number;
175
- previous_cursor: string;
175
+ prev_cursor: string;
176
176
  next_cursor: string;
177
177
  next_page_url?: string;
178
- previous_page_url?: string;
178
+ prev_page_url?: string;
179
179
  }
180
180
  interface SimplePaginatorMeta {
181
181
  path: string;
@@ -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.WritableComputedRef<boolean | undefined>;
227
+ show: vue.WritableComputedRef<boolean | undefined, boolean | undefined>;
228
228
  /** Properties of the dialog. */
229
229
  properties: vue.ComputedRef<Properties | undefined>;
230
230
  };
@@ -522,8 +522,8 @@ declare function useRefinements<Properties extends object, RefinementsKey extend
522
522
  };
523
523
 
524
524
  declare function useRoute(): {
525
- isNavigating: Readonly<vue.Ref<boolean>>;
526
- current: Readonly<vue.Ref<string | undefined>>;
525
+ isNavigating: Readonly<vue.Ref<boolean, boolean>>;
526
+ current: Readonly<vue.Ref<string | undefined, string | undefined>>;
527
527
  matches: <T extends RouteName>(name: MaybeRefOrGetter<T>, parameters?: RouteParameters<T>) => boolean;
528
528
  };
529
529
 
@@ -543,7 +543,12 @@ declare function useBulkSelect<T = any>(): {
543
543
  deselect: (...records: T[]) => void;
544
544
  toggle: (record: T, force?: boolean) => void;
545
545
  selected: (record: T) => boolean;
546
- selection: Ref<BulkSelection<T>>;
546
+ selection: Ref<BulkSelection<T>, BulkSelection<T>>;
547
+ bindCheckbox: (key: T) => {
548
+ onChange: (event: Event) => void;
549
+ checked: boolean;
550
+ value: T;
551
+ };
547
552
  };
548
553
 
549
554
  declare global {
@@ -597,11 +602,22 @@ type AsRecordType<T extends Record<string, any>> = {
597
602
  value: T[K];
598
603
  };
599
604
  };
605
+ interface TableDefaultOptions extends AvailableHybridRequestOptions {
606
+ /**
607
+ * Whether to include existing query parameters in the request.
608
+ * @default true
609
+ */
610
+ includeQueryParameters?: boolean;
611
+ /**
612
+ * Additionnal data to send with the requests.
613
+ */
614
+ data?: Record<string, FormDataConvertible> | FormDataConvertible;
615
+ }
600
616
  /**
601
617
  * Provides utilities for working with tables.
602
618
  */
603
- declare function useTable<RecordType extends (Props[PropsKey] extends Table<infer T, any> ? AsRecordType<T> : never), PaginatorKindName extends (Props[PropsKey] extends Table<RecordType, infer PaginatorKind> ? PaginatorKind : never), TableType extends (Props[PropsKey] extends Table<RecordType, PaginatorKindName> ? Table<RecordType, PaginatorKindName> : never), Props extends Record<string, unknown>, PropsKey extends keyof Props>(props: Props, key: PropsKey, defaultOptions?: AvailableHybridRequestOptions): {
604
- bindFilter: <T = any>(name: string, options?: BindFilterOptions<T>) => vue.Ref<T>;
619
+ declare function useTable<RecordType extends (Props[PropsKey] extends Table<infer T, any> ? AsRecordType<T> : never), PaginatorKindName extends (Props[PropsKey] extends Table<any, infer PaginatorKind> ? PaginatorKind : never), TableType extends (Props[PropsKey] extends Table<any, PaginatorKindName> ? Table<RecordType, PaginatorKindName> : never), Props extends Record<string, unknown>, PropsKey extends keyof Props>(props: Props, key: PropsKey, defaultOptions?: TableDefaultOptions): {
620
+ bindFilter: <T = any>(name: string, options?: BindFilterOptions<T>) => vue.Ref<T, T>;
605
621
  filters: {
606
622
  apply: (value: any, options?: AvailableHybridRequestOptions) => Promise<_hybridly_core.NavigationResponse | undefined>;
607
623
  clear: (options?: AvailableHybridRequestOptions) => Promise<_hybridly_core.NavigationResponse>;
@@ -619,8 +635,8 @@ declare function useTable<RecordType extends (Props[PropsKey] extends Table<infe
619
635
  isSorting: (direction?: SortDirection) => boolean;
620
636
  clear: (options?: AvailableHybridRequestOptions) => Promise<_hybridly_core.NavigationResponse>;
621
637
  is_active: boolean;
622
- direction?: SortDirection;
623
- default?: SortDirection;
638
+ direction?: SortDirection | undefined;
639
+ default?: SortDirection | undefined;
624
640
  label: string;
625
641
  metadata: Record<string, any>;
626
642
  name: string;
@@ -650,6 +666,11 @@ declare function useTable<RecordType extends (Props[PropsKey] extends Table<infe
650
666
  isSelected: (record: RecordType) => boolean;
651
667
  allSelected: boolean;
652
668
  selection: BulkSelection<RecordIdentifier>;
669
+ bindCheckbox: (key: RecordIdentifier) => {
670
+ onChange: (event: Event) => void;
671
+ checked: boolean;
672
+ value: RecordIdentifier;
673
+ };
653
674
  toggle: (record: RecordType) => void;
654
675
  select: (record: RecordType) => void;
655
676
  deselect: (record: RecordType) => void;
@@ -829,7 +850,54 @@ interface SetupArguments {
829
850
  payload: Record<string, any>;
830
851
  }
831
852
 
832
- declare const RouterLink: vue.DefineComponent<{
853
+ declare const RouterLink: vue.DefineComponent<vue.ExtractPropTypes<{
854
+ href: {
855
+ type: StringConstructor;
856
+ required: false;
857
+ default: undefined;
858
+ };
859
+ as: {
860
+ type: (ObjectConstructor | StringConstructor)[];
861
+ default: string;
862
+ };
863
+ method: {
864
+ type: PropType<Method | Lowercase<Method>>;
865
+ default: string;
866
+ };
867
+ data: {
868
+ type: PropType<RequestData>;
869
+ default: () => {};
870
+ };
871
+ external: {
872
+ type: BooleanConstructor;
873
+ default: boolean;
874
+ };
875
+ disabled: {
876
+ type: BooleanConstructor;
877
+ default: boolean;
878
+ };
879
+ options: {
880
+ type: PropType<Omit<HybridRequestOptions, "url" | "data" | "method">>;
881
+ default: () => {};
882
+ };
883
+ text: {
884
+ type: StringConstructor;
885
+ required: false;
886
+ default: undefined;
887
+ };
888
+ preload: {
889
+ type: PropType<boolean | "hover" | "mount">;
890
+ default: boolean;
891
+ };
892
+ preserveScroll: {
893
+ type: BooleanConstructor;
894
+ default: undefined;
895
+ };
896
+ preserveState: {
897
+ type: BooleanConstructor;
898
+ default: undefined;
899
+ };
900
+ }>, (props: _vue_shared.LooseRequired<Readonly<vue.ExtractPropTypes<{
833
901
  href: {
834
902
  type: StringConstructor;
835
903
  required: false;
@@ -876,21 +944,9 @@ declare const RouterLink: vue.DefineComponent<{
876
944
  type: BooleanConstructor;
877
945
  default: undefined;
878
946
  };
879
- }, (props: _vue_shared.LooseRequired<{
880
- readonly data: RequestData;
881
- readonly method: "delete" | Method | "get" | "post" | "put" | "patch";
882
- readonly options: Omit<HybridRequestOptions, "data" | "url" | "method">;
883
- readonly as: string | Record<string, any>;
884
- readonly external: boolean;
885
- readonly disabled: boolean;
886
- readonly preload: boolean | "hover" | "mount";
887
- readonly text?: string | undefined;
888
- readonly preserveScroll?: boolean | undefined;
889
- readonly preserveState?: boolean | undefined;
890
- readonly href?: string | undefined;
891
- } & {}>) => vue.VNode<vue.RendererNode, vue.RendererElement, {
947
+ }>> & Readonly<{}> & {}>) => vue.VNode<vue.RendererNode, vue.RendererElement, {
892
948
  [key: string]: any;
893
- }>, unknown, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.PublicProps, Readonly<vue.ExtractPropTypes<{
949
+ }>, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.PublicProps, Readonly<vue.ExtractPropTypes<{
894
950
  href: {
895
951
  type: StringConstructor;
896
952
  required: false;
@@ -937,7 +993,7 @@ declare const RouterLink: vue.DefineComponent<{
937
993
  type: BooleanConstructor;
938
994
  default: undefined;
939
995
  };
940
- }>>, {
996
+ }>> & Readonly<{}>, {
941
997
  data: RequestData;
942
998
  text: string;
943
999
  preserveScroll: boolean;
@@ -949,6 +1005,6 @@ declare const RouterLink: vue.DefineComponent<{
949
1005
  external: boolean;
950
1006
  disabled: boolean;
951
1007
  preload: boolean | "hover" | "mount";
952
- }, {}>;
1008
+ }, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
953
1009
 
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 };
1010
+ 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 TableDefaultOptions, type ToggleSortOptions, initializeHybridly, registerHook, setProperty, useBackForward, useBulkSelect, useDialog, useForm, useHistoryState, useProperties, useProperty, useQueryParameter, useQueryParameters, useRefinements, useRoute, useTable };
package/dist/index.d.mts CHANGED
@@ -4,9 +4,9 @@ import * as _hybridly_core from '@hybridly/core';
4
4
  import { HybridRequestOptions, UrlResolvable, RouterContext, registerHook as registerHook$1, RouteName, RouteParameters, RouterContextOptions, Plugin, Method } from '@hybridly/core';
5
5
  export { can, route, router } from '@hybridly/core';
6
6
  import { Axios } from 'axios';
7
+ import * as _vue_shared from '@vue/shared';
7
8
  import { SearchableObject, Path, PathValue } from '@clickbar/dot-diver';
8
9
  import { FormDataConvertible, RequestData } from '@hybridly/utils';
9
- import * as _vue_shared from '@vue/shared';
10
10
 
11
11
  interface ProgressOptions {
12
12
  /**
@@ -94,20 +94,20 @@ declare function useForm<T extends SearchableObject, P extends Path<T> & string
94
94
  progress: {
95
95
  readonly event: {
96
96
  readonly loaded: number;
97
- readonly total?: number;
98
- readonly progress?: number;
97
+ readonly total?: number | undefined;
98
+ readonly progress?: number | undefined;
99
99
  readonly bytes: number;
100
- readonly rate?: number;
101
- readonly estimated?: number;
102
- readonly upload?: boolean;
103
- readonly download?: boolean;
100
+ readonly rate?: number | undefined;
101
+ readonly estimated?: number | undefined;
102
+ readonly upload?: boolean | undefined;
103
+ readonly download?: boolean | undefined;
104
104
  readonly event?: any;
105
105
  readonly lengthComputable: boolean;
106
106
  };
107
107
  readonly percentage: Readonly<number>;
108
108
  } | undefined;
109
109
  isDirty: boolean;
110
- errors: DeepReadonly<vue.UnwrapRef<Errors<T>>>;
110
+ errors: vue.UnwrapRef<DeepReadonly<[Errors<T>] extends [vue.Ref<any, any>] ? _vue_shared.IfAny<vue.Ref<any, any> & Errors<T>, vue.Ref<vue.Ref<any, any> & Errors<T>, vue.Ref<any, any> & Errors<T>>, vue.Ref<any, any> & Errors<T>> : vue.Ref<vue.UnwrapRef<Errors<T>>, Errors<T> | vue.UnwrapRef<Errors<T>>>>>;
111
111
  processing: boolean;
112
112
  successful: boolean;
113
113
  failed: boolean;
@@ -119,7 +119,7 @@ declare function useForm<T extends SearchableObject, P extends Path<T> & string
119
119
  * Returns a ref with a value saved in the history state through Hybridly.
120
120
  * The state is linked to a specific browser history entry.
121
121
  */
122
- declare function useHistoryState<T = any>(key: string, initial: T): vue.Ref<vue.UnwrapRef<T>>;
122
+ declare function useHistoryState<T = any>(key: string, initial: T): [T] extends [vue.Ref<any, any>] ? _vue_shared.IfAny<T, vue.Ref<T, T>, T> : vue.Ref<vue.UnwrapRef<T>, T | vue.UnwrapRef<T>>;
123
123
 
124
124
  type BackForwardCallback = (context: RouterContext) => void;
125
125
  interface UseBackForwardOptions {
@@ -172,10 +172,10 @@ interface PaginatorLink {
172
172
  interface CursorPaginatorMeta {
173
173
  path: string;
174
174
  per_page: number;
175
- previous_cursor: string;
175
+ prev_cursor: string;
176
176
  next_cursor: string;
177
177
  next_page_url?: string;
178
- previous_page_url?: string;
178
+ prev_page_url?: string;
179
179
  }
180
180
  interface SimplePaginatorMeta {
181
181
  path: string;
@@ -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.WritableComputedRef<boolean | undefined>;
227
+ show: vue.WritableComputedRef<boolean | undefined, boolean | undefined>;
228
228
  /** Properties of the dialog. */
229
229
  properties: vue.ComputedRef<Properties | undefined>;
230
230
  };
@@ -522,8 +522,8 @@ declare function useRefinements<Properties extends object, RefinementsKey extend
522
522
  };
523
523
 
524
524
  declare function useRoute(): {
525
- isNavigating: Readonly<vue.Ref<boolean>>;
526
- current: Readonly<vue.Ref<string | undefined>>;
525
+ isNavigating: Readonly<vue.Ref<boolean, boolean>>;
526
+ current: Readonly<vue.Ref<string | undefined, string | undefined>>;
527
527
  matches: <T extends RouteName>(name: MaybeRefOrGetter<T>, parameters?: RouteParameters<T>) => boolean;
528
528
  };
529
529
 
@@ -543,7 +543,12 @@ declare function useBulkSelect<T = any>(): {
543
543
  deselect: (...records: T[]) => void;
544
544
  toggle: (record: T, force?: boolean) => void;
545
545
  selected: (record: T) => boolean;
546
- selection: Ref<BulkSelection<T>>;
546
+ selection: Ref<BulkSelection<T>, BulkSelection<T>>;
547
+ bindCheckbox: (key: T) => {
548
+ onChange: (event: Event) => void;
549
+ checked: boolean;
550
+ value: T;
551
+ };
547
552
  };
548
553
 
549
554
  declare global {
@@ -597,11 +602,22 @@ type AsRecordType<T extends Record<string, any>> = {
597
602
  value: T[K];
598
603
  };
599
604
  };
605
+ interface TableDefaultOptions extends AvailableHybridRequestOptions {
606
+ /**
607
+ * Whether to include existing query parameters in the request.
608
+ * @default true
609
+ */
610
+ includeQueryParameters?: boolean;
611
+ /**
612
+ * Additionnal data to send with the requests.
613
+ */
614
+ data?: Record<string, FormDataConvertible> | FormDataConvertible;
615
+ }
600
616
  /**
601
617
  * Provides utilities for working with tables.
602
618
  */
603
- declare function useTable<RecordType extends (Props[PropsKey] extends Table<infer T, any> ? AsRecordType<T> : never), PaginatorKindName extends (Props[PropsKey] extends Table<RecordType, infer PaginatorKind> ? PaginatorKind : never), TableType extends (Props[PropsKey] extends Table<RecordType, PaginatorKindName> ? Table<RecordType, PaginatorKindName> : never), Props extends Record<string, unknown>, PropsKey extends keyof Props>(props: Props, key: PropsKey, defaultOptions?: AvailableHybridRequestOptions): {
604
- bindFilter: <T = any>(name: string, options?: BindFilterOptions<T>) => vue.Ref<T>;
619
+ declare function useTable<RecordType extends (Props[PropsKey] extends Table<infer T, any> ? AsRecordType<T> : never), PaginatorKindName extends (Props[PropsKey] extends Table<any, infer PaginatorKind> ? PaginatorKind : never), TableType extends (Props[PropsKey] extends Table<any, PaginatorKindName> ? Table<RecordType, PaginatorKindName> : never), Props extends Record<string, unknown>, PropsKey extends keyof Props>(props: Props, key: PropsKey, defaultOptions?: TableDefaultOptions): {
620
+ bindFilter: <T = any>(name: string, options?: BindFilterOptions<T>) => vue.Ref<T, T>;
605
621
  filters: {
606
622
  apply: (value: any, options?: AvailableHybridRequestOptions) => Promise<_hybridly_core.NavigationResponse | undefined>;
607
623
  clear: (options?: AvailableHybridRequestOptions) => Promise<_hybridly_core.NavigationResponse>;
@@ -619,8 +635,8 @@ declare function useTable<RecordType extends (Props[PropsKey] extends Table<infe
619
635
  isSorting: (direction?: SortDirection) => boolean;
620
636
  clear: (options?: AvailableHybridRequestOptions) => Promise<_hybridly_core.NavigationResponse>;
621
637
  is_active: boolean;
622
- direction?: SortDirection;
623
- default?: SortDirection;
638
+ direction?: SortDirection | undefined;
639
+ default?: SortDirection | undefined;
624
640
  label: string;
625
641
  metadata: Record<string, any>;
626
642
  name: string;
@@ -650,6 +666,11 @@ declare function useTable<RecordType extends (Props[PropsKey] extends Table<infe
650
666
  isSelected: (record: RecordType) => boolean;
651
667
  allSelected: boolean;
652
668
  selection: BulkSelection<RecordIdentifier>;
669
+ bindCheckbox: (key: RecordIdentifier) => {
670
+ onChange: (event: Event) => void;
671
+ checked: boolean;
672
+ value: RecordIdentifier;
673
+ };
653
674
  toggle: (record: RecordType) => void;
654
675
  select: (record: RecordType) => void;
655
676
  deselect: (record: RecordType) => void;
@@ -829,7 +850,54 @@ interface SetupArguments {
829
850
  payload: Record<string, any>;
830
851
  }
831
852
 
832
- declare const RouterLink: vue.DefineComponent<{
853
+ declare const RouterLink: vue.DefineComponent<vue.ExtractPropTypes<{
854
+ href: {
855
+ type: StringConstructor;
856
+ required: false;
857
+ default: undefined;
858
+ };
859
+ as: {
860
+ type: (ObjectConstructor | StringConstructor)[];
861
+ default: string;
862
+ };
863
+ method: {
864
+ type: PropType<Method | Lowercase<Method>>;
865
+ default: string;
866
+ };
867
+ data: {
868
+ type: PropType<RequestData>;
869
+ default: () => {};
870
+ };
871
+ external: {
872
+ type: BooleanConstructor;
873
+ default: boolean;
874
+ };
875
+ disabled: {
876
+ type: BooleanConstructor;
877
+ default: boolean;
878
+ };
879
+ options: {
880
+ type: PropType<Omit<HybridRequestOptions, "url" | "data" | "method">>;
881
+ default: () => {};
882
+ };
883
+ text: {
884
+ type: StringConstructor;
885
+ required: false;
886
+ default: undefined;
887
+ };
888
+ preload: {
889
+ type: PropType<boolean | "hover" | "mount">;
890
+ default: boolean;
891
+ };
892
+ preserveScroll: {
893
+ type: BooleanConstructor;
894
+ default: undefined;
895
+ };
896
+ preserveState: {
897
+ type: BooleanConstructor;
898
+ default: undefined;
899
+ };
900
+ }>, (props: _vue_shared.LooseRequired<Readonly<vue.ExtractPropTypes<{
833
901
  href: {
834
902
  type: StringConstructor;
835
903
  required: false;
@@ -876,21 +944,9 @@ declare const RouterLink: vue.DefineComponent<{
876
944
  type: BooleanConstructor;
877
945
  default: undefined;
878
946
  };
879
- }, (props: _vue_shared.LooseRequired<{
880
- readonly data: RequestData;
881
- readonly method: "delete" | Method | "get" | "post" | "put" | "patch";
882
- readonly options: Omit<HybridRequestOptions, "data" | "url" | "method">;
883
- readonly as: string | Record<string, any>;
884
- readonly external: boolean;
885
- readonly disabled: boolean;
886
- readonly preload: boolean | "hover" | "mount";
887
- readonly text?: string | undefined;
888
- readonly preserveScroll?: boolean | undefined;
889
- readonly preserveState?: boolean | undefined;
890
- readonly href?: string | undefined;
891
- } & {}>) => vue.VNode<vue.RendererNode, vue.RendererElement, {
947
+ }>> & Readonly<{}> & {}>) => vue.VNode<vue.RendererNode, vue.RendererElement, {
892
948
  [key: string]: any;
893
- }>, unknown, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.PublicProps, Readonly<vue.ExtractPropTypes<{
949
+ }>, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.PublicProps, Readonly<vue.ExtractPropTypes<{
894
950
  href: {
895
951
  type: StringConstructor;
896
952
  required: false;
@@ -937,7 +993,7 @@ declare const RouterLink: vue.DefineComponent<{
937
993
  type: BooleanConstructor;
938
994
  default: undefined;
939
995
  };
940
- }>>, {
996
+ }>> & Readonly<{}>, {
941
997
  data: RequestData;
942
998
  text: string;
943
999
  preserveScroll: boolean;
@@ -949,6 +1005,6 @@ declare const RouterLink: vue.DefineComponent<{
949
1005
  external: boolean;
950
1006
  disabled: boolean;
951
1007
  preload: boolean | "hover" | "mount";
952
- }, {}>;
1008
+ }, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
953
1009
 
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 };
1010
+ 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 TableDefaultOptions, type ToggleSortOptions, initializeHybridly, registerHook, setProperty, useBackForward, useBulkSelect, useDialog, useForm, useHistoryState, useProperties, useProperty, useQueryParameter, useQueryParameters, useRefinements, useRoute, useTable };
package/dist/index.d.ts CHANGED
@@ -4,9 +4,9 @@ import * as _hybridly_core from '@hybridly/core';
4
4
  import { HybridRequestOptions, UrlResolvable, RouterContext, registerHook as registerHook$1, RouteName, RouteParameters, RouterContextOptions, Plugin, Method } from '@hybridly/core';
5
5
  export { can, route, router } from '@hybridly/core';
6
6
  import { Axios } from 'axios';
7
+ import * as _vue_shared from '@vue/shared';
7
8
  import { SearchableObject, Path, PathValue } from '@clickbar/dot-diver';
8
9
  import { FormDataConvertible, RequestData } from '@hybridly/utils';
9
- import * as _vue_shared from '@vue/shared';
10
10
 
11
11
  interface ProgressOptions {
12
12
  /**
@@ -94,20 +94,20 @@ declare function useForm<T extends SearchableObject, P extends Path<T> & string
94
94
  progress: {
95
95
  readonly event: {
96
96
  readonly loaded: number;
97
- readonly total?: number;
98
- readonly progress?: number;
97
+ readonly total?: number | undefined;
98
+ readonly progress?: number | undefined;
99
99
  readonly bytes: number;
100
- readonly rate?: number;
101
- readonly estimated?: number;
102
- readonly upload?: boolean;
103
- readonly download?: boolean;
100
+ readonly rate?: number | undefined;
101
+ readonly estimated?: number | undefined;
102
+ readonly upload?: boolean | undefined;
103
+ readonly download?: boolean | undefined;
104
104
  readonly event?: any;
105
105
  readonly lengthComputable: boolean;
106
106
  };
107
107
  readonly percentage: Readonly<number>;
108
108
  } | undefined;
109
109
  isDirty: boolean;
110
- errors: DeepReadonly<vue.UnwrapRef<Errors<T>>>;
110
+ errors: vue.UnwrapRef<DeepReadonly<[Errors<T>] extends [vue.Ref<any, any>] ? _vue_shared.IfAny<vue.Ref<any, any> & Errors<T>, vue.Ref<vue.Ref<any, any> & Errors<T>, vue.Ref<any, any> & Errors<T>>, vue.Ref<any, any> & Errors<T>> : vue.Ref<vue.UnwrapRef<Errors<T>>, Errors<T> | vue.UnwrapRef<Errors<T>>>>>;
111
111
  processing: boolean;
112
112
  successful: boolean;
113
113
  failed: boolean;
@@ -119,7 +119,7 @@ declare function useForm<T extends SearchableObject, P extends Path<T> & string
119
119
  * Returns a ref with a value saved in the history state through Hybridly.
120
120
  * The state is linked to a specific browser history entry.
121
121
  */
122
- declare function useHistoryState<T = any>(key: string, initial: T): vue.Ref<vue.UnwrapRef<T>>;
122
+ declare function useHistoryState<T = any>(key: string, initial: T): [T] extends [vue.Ref<any, any>] ? _vue_shared.IfAny<T, vue.Ref<T, T>, T> : vue.Ref<vue.UnwrapRef<T>, T | vue.UnwrapRef<T>>;
123
123
 
124
124
  type BackForwardCallback = (context: RouterContext) => void;
125
125
  interface UseBackForwardOptions {
@@ -172,10 +172,10 @@ interface PaginatorLink {
172
172
  interface CursorPaginatorMeta {
173
173
  path: string;
174
174
  per_page: number;
175
- previous_cursor: string;
175
+ prev_cursor: string;
176
176
  next_cursor: string;
177
177
  next_page_url?: string;
178
- previous_page_url?: string;
178
+ prev_page_url?: string;
179
179
  }
180
180
  interface SimplePaginatorMeta {
181
181
  path: string;
@@ -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.WritableComputedRef<boolean | undefined>;
227
+ show: vue.WritableComputedRef<boolean | undefined, boolean | undefined>;
228
228
  /** Properties of the dialog. */
229
229
  properties: vue.ComputedRef<Properties | undefined>;
230
230
  };
@@ -522,8 +522,8 @@ declare function useRefinements<Properties extends object, RefinementsKey extend
522
522
  };
523
523
 
524
524
  declare function useRoute(): {
525
- isNavigating: Readonly<vue.Ref<boolean>>;
526
- current: Readonly<vue.Ref<string | undefined>>;
525
+ isNavigating: Readonly<vue.Ref<boolean, boolean>>;
526
+ current: Readonly<vue.Ref<string | undefined, string | undefined>>;
527
527
  matches: <T extends RouteName>(name: MaybeRefOrGetter<T>, parameters?: RouteParameters<T>) => boolean;
528
528
  };
529
529
 
@@ -543,7 +543,12 @@ declare function useBulkSelect<T = any>(): {
543
543
  deselect: (...records: T[]) => void;
544
544
  toggle: (record: T, force?: boolean) => void;
545
545
  selected: (record: T) => boolean;
546
- selection: Ref<BulkSelection<T>>;
546
+ selection: Ref<BulkSelection<T>, BulkSelection<T>>;
547
+ bindCheckbox: (key: T) => {
548
+ onChange: (event: Event) => void;
549
+ checked: boolean;
550
+ value: T;
551
+ };
547
552
  };
548
553
 
549
554
  declare global {
@@ -597,11 +602,22 @@ type AsRecordType<T extends Record<string, any>> = {
597
602
  value: T[K];
598
603
  };
599
604
  };
605
+ interface TableDefaultOptions extends AvailableHybridRequestOptions {
606
+ /**
607
+ * Whether to include existing query parameters in the request.
608
+ * @default true
609
+ */
610
+ includeQueryParameters?: boolean;
611
+ /**
612
+ * Additionnal data to send with the requests.
613
+ */
614
+ data?: Record<string, FormDataConvertible> | FormDataConvertible;
615
+ }
600
616
  /**
601
617
  * Provides utilities for working with tables.
602
618
  */
603
- declare function useTable<RecordType extends (Props[PropsKey] extends Table<infer T, any> ? AsRecordType<T> : never), PaginatorKindName extends (Props[PropsKey] extends Table<RecordType, infer PaginatorKind> ? PaginatorKind : never), TableType extends (Props[PropsKey] extends Table<RecordType, PaginatorKindName> ? Table<RecordType, PaginatorKindName> : never), Props extends Record<string, unknown>, PropsKey extends keyof Props>(props: Props, key: PropsKey, defaultOptions?: AvailableHybridRequestOptions): {
604
- bindFilter: <T = any>(name: string, options?: BindFilterOptions<T>) => vue.Ref<T>;
619
+ declare function useTable<RecordType extends (Props[PropsKey] extends Table<infer T, any> ? AsRecordType<T> : never), PaginatorKindName extends (Props[PropsKey] extends Table<any, infer PaginatorKind> ? PaginatorKind : never), TableType extends (Props[PropsKey] extends Table<any, PaginatorKindName> ? Table<RecordType, PaginatorKindName> : never), Props extends Record<string, unknown>, PropsKey extends keyof Props>(props: Props, key: PropsKey, defaultOptions?: TableDefaultOptions): {
620
+ bindFilter: <T = any>(name: string, options?: BindFilterOptions<T>) => vue.Ref<T, T>;
605
621
  filters: {
606
622
  apply: (value: any, options?: AvailableHybridRequestOptions) => Promise<_hybridly_core.NavigationResponse | undefined>;
607
623
  clear: (options?: AvailableHybridRequestOptions) => Promise<_hybridly_core.NavigationResponse>;
@@ -619,8 +635,8 @@ declare function useTable<RecordType extends (Props[PropsKey] extends Table<infe
619
635
  isSorting: (direction?: SortDirection) => boolean;
620
636
  clear: (options?: AvailableHybridRequestOptions) => Promise<_hybridly_core.NavigationResponse>;
621
637
  is_active: boolean;
622
- direction?: SortDirection;
623
- default?: SortDirection;
638
+ direction?: SortDirection | undefined;
639
+ default?: SortDirection | undefined;
624
640
  label: string;
625
641
  metadata: Record<string, any>;
626
642
  name: string;
@@ -650,6 +666,11 @@ declare function useTable<RecordType extends (Props[PropsKey] extends Table<infe
650
666
  isSelected: (record: RecordType) => boolean;
651
667
  allSelected: boolean;
652
668
  selection: BulkSelection<RecordIdentifier>;
669
+ bindCheckbox: (key: RecordIdentifier) => {
670
+ onChange: (event: Event) => void;
671
+ checked: boolean;
672
+ value: RecordIdentifier;
673
+ };
653
674
  toggle: (record: RecordType) => void;
654
675
  select: (record: RecordType) => void;
655
676
  deselect: (record: RecordType) => void;
@@ -829,7 +850,54 @@ interface SetupArguments {
829
850
  payload: Record<string, any>;
830
851
  }
831
852
 
832
- declare const RouterLink: vue.DefineComponent<{
853
+ declare const RouterLink: vue.DefineComponent<vue.ExtractPropTypes<{
854
+ href: {
855
+ type: StringConstructor;
856
+ required: false;
857
+ default: undefined;
858
+ };
859
+ as: {
860
+ type: (ObjectConstructor | StringConstructor)[];
861
+ default: string;
862
+ };
863
+ method: {
864
+ type: PropType<Method | Lowercase<Method>>;
865
+ default: string;
866
+ };
867
+ data: {
868
+ type: PropType<RequestData>;
869
+ default: () => {};
870
+ };
871
+ external: {
872
+ type: BooleanConstructor;
873
+ default: boolean;
874
+ };
875
+ disabled: {
876
+ type: BooleanConstructor;
877
+ default: boolean;
878
+ };
879
+ options: {
880
+ type: PropType<Omit<HybridRequestOptions, "url" | "data" | "method">>;
881
+ default: () => {};
882
+ };
883
+ text: {
884
+ type: StringConstructor;
885
+ required: false;
886
+ default: undefined;
887
+ };
888
+ preload: {
889
+ type: PropType<boolean | "hover" | "mount">;
890
+ default: boolean;
891
+ };
892
+ preserveScroll: {
893
+ type: BooleanConstructor;
894
+ default: undefined;
895
+ };
896
+ preserveState: {
897
+ type: BooleanConstructor;
898
+ default: undefined;
899
+ };
900
+ }>, (props: _vue_shared.LooseRequired<Readonly<vue.ExtractPropTypes<{
833
901
  href: {
834
902
  type: StringConstructor;
835
903
  required: false;
@@ -876,21 +944,9 @@ declare const RouterLink: vue.DefineComponent<{
876
944
  type: BooleanConstructor;
877
945
  default: undefined;
878
946
  };
879
- }, (props: _vue_shared.LooseRequired<{
880
- readonly data: RequestData;
881
- readonly method: "delete" | Method | "get" | "post" | "put" | "patch";
882
- readonly options: Omit<HybridRequestOptions, "data" | "url" | "method">;
883
- readonly as: string | Record<string, any>;
884
- readonly external: boolean;
885
- readonly disabled: boolean;
886
- readonly preload: boolean | "hover" | "mount";
887
- readonly text?: string | undefined;
888
- readonly preserveScroll?: boolean | undefined;
889
- readonly preserveState?: boolean | undefined;
890
- readonly href?: string | undefined;
891
- } & {}>) => vue.VNode<vue.RendererNode, vue.RendererElement, {
947
+ }>> & Readonly<{}> & {}>) => vue.VNode<vue.RendererNode, vue.RendererElement, {
892
948
  [key: string]: any;
893
- }>, unknown, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.PublicProps, Readonly<vue.ExtractPropTypes<{
949
+ }>, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.PublicProps, Readonly<vue.ExtractPropTypes<{
894
950
  href: {
895
951
  type: StringConstructor;
896
952
  required: false;
@@ -937,7 +993,7 @@ declare const RouterLink: vue.DefineComponent<{
937
993
  type: BooleanConstructor;
938
994
  default: undefined;
939
995
  };
940
- }>>, {
996
+ }>> & Readonly<{}>, {
941
997
  data: RequestData;
942
998
  text: string;
943
999
  preserveScroll: boolean;
@@ -949,6 +1005,6 @@ declare const RouterLink: vue.DefineComponent<{
949
1005
  external: boolean;
950
1006
  disabled: boolean;
951
1007
  preload: boolean | "hover" | "mount";
952
- }, {}>;
1008
+ }, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
953
1009
 
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 };
1010
+ 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 TableDefaultOptions, type ToggleSortOptions, initializeHybridly, registerHook, setProperty, useBackForward, useBulkSelect, useDialog, useForm, useHistoryState, useProperties, useProperty, useQueryParameter, useQueryParameters, useRefinements, useRoute, useTable };
package/dist/index.mjs CHANGED
@@ -193,7 +193,10 @@ const wrapper = defineComponent({
193
193
  function renderLayout(view) {
194
194
  debug.adapter("vue:render:layout", "Rendering layout.");
195
195
  if (typeof state.view.value?.layout === "function") {
196
- return state.view.value.layout(h, view, renderDialog());
196
+ return state.view.value.layout(h, view, renderDialog(), {
197
+ ...state.view.value?.properties ?? {},
198
+ ...state.properties.value
199
+ });
197
200
  }
198
201
  if (Array.isArray(state.view.value?.layout)) {
199
202
  const layoutsAndView = state.view.value.layout.concat(view).reverse().reduce((child, layout) => {
@@ -589,6 +592,9 @@ Please specify a more appropriate element using the "as" attribute. For example:
589
592
  ...props.disabled ? { disabled: props.disabled } : {},
590
593
  onMouseenter: () => performPreload("hover"),
591
594
  onClick: (event) => {
595
+ if (props.disabled) {
596
+ return;
597
+ }
592
598
  if (props.external) {
593
599
  return;
594
600
  }
@@ -596,9 +602,6 @@ Please specify a more appropriate element using the "as" attribute. For example:
596
602
  return;
597
603
  }
598
604
  event.preventDefault();
599
- if (props.disabled) {
600
- return;
601
- }
602
605
  router.navigate({
603
606
  url,
604
607
  data,
@@ -993,7 +996,7 @@ function useRefinements(properties, refinementsKeys, defaultOptions = {}) {
993
996
  async function applyFilter(name, value, options = {}) {
994
997
  const filter = getFilter(name);
995
998
  if (!filter) {
996
- console.warn(`[Refinement] Filter "${name} does not exist."`);
999
+ console.warn(`[Refinement] Filter "${name}" does not exist.`);
997
1000
  return;
998
1001
  }
999
1002
  if (["", null].includes(value) || value === filter.default) {
@@ -1039,7 +1042,7 @@ function useRefinements(properties, refinementsKeys, defaultOptions = {}) {
1039
1042
  async function toggleSort(name, options) {
1040
1043
  const sort = getSort(name);
1041
1044
  if (!sort) {
1042
- console.warn(`[Refinement] Sort "${name} does not exist."`);
1045
+ console.warn(`[Refinement] Sort "${name}" does not exist.`);
1043
1046
  return;
1044
1047
  }
1045
1048
  const next = options?.direction ? sort[options?.direction] : sort.next;
@@ -1238,6 +1241,20 @@ function useBulkSelect() {
1238
1241
  const allSelected = computed(() => {
1239
1242
  return selection.value.all && selection.value.except.size === 0;
1240
1243
  });
1244
+ function bindCheckbox(key) {
1245
+ return {
1246
+ onChange: (event) => {
1247
+ const target = event.target;
1248
+ if (target.checked) {
1249
+ select(target.value);
1250
+ } else {
1251
+ deselect(target.value);
1252
+ }
1253
+ },
1254
+ checked: selected(key),
1255
+ value: key
1256
+ };
1257
+ }
1241
1258
  return {
1242
1259
  allSelected,
1243
1260
  selectAll,
@@ -1246,20 +1263,70 @@ function useBulkSelect() {
1246
1263
  deselect,
1247
1264
  toggle,
1248
1265
  selected,
1249
- selection
1266
+ selection,
1267
+ bindCheckbox
1250
1268
  };
1251
1269
  }
1252
1270
 
1271
+ function useQueryParameters() {
1272
+ const state = reactive({});
1273
+ function updateState() {
1274
+ const params = new URLSearchParams(window.location.search);
1275
+ const unusedKeys = new Set(Object.keys(state));
1276
+ for (const key of params.keys()) {
1277
+ const paramsForKey = params.getAll(key);
1278
+ state[key] = paramsForKey.length > 1 ? paramsForKey : params.get(key) || "";
1279
+ unusedKeys.delete(key);
1280
+ }
1281
+ Array.from(unusedKeys).forEach((key) => delete state[key]);
1282
+ }
1283
+ updateState();
1284
+ registerHook$1("after", updateState);
1285
+ return state;
1286
+ }
1287
+ function useQueryParameter(name, options = {}) {
1288
+ const query = useQueryParameters();
1289
+ const transform = (value2) => {
1290
+ if (options.transform === "bool") {
1291
+ return value2 === true || value2 === "true" || value2 === "1" || value2 === "yes";
1292
+ } else if (options.transform === "number") {
1293
+ return Number(value2);
1294
+ } else if (options.transform === "string") {
1295
+ return String(value2);
1296
+ } else if (options.transform === "date") {
1297
+ return new Date(value2);
1298
+ } else if (typeof options.transform === "function") {
1299
+ return options.transform(value2);
1300
+ }
1301
+ return value2;
1302
+ };
1303
+ const value = ref();
1304
+ watch(query, () => {
1305
+ value.value = transform(query[name] ?? toValue(options.defaultValue));
1306
+ }, { deep: true, immediate: true });
1307
+ return value;
1308
+ }
1309
+
1253
1310
  function useTable(props, key, defaultOptions = {}) {
1254
1311
  const table = computed(() => props[key]);
1255
1312
  const bulk = useBulkSelect();
1256
1313
  const refinements = useRefinements(toReactive(table), "refinements", defaultOptions);
1314
+ function getAdditionnalData() {
1315
+ const data = {};
1316
+ if (defaultOptions?.includeQueryParameters !== false) {
1317
+ Object.assign(data, structuredClone(toRaw(useQueryParameters())));
1318
+ }
1319
+ if (defaultOptions?.data) {
1320
+ Object.assign(data, defaultOptions.data);
1321
+ }
1322
+ return data;
1323
+ }
1257
1324
  function getRecordKey(record) {
1258
1325
  if (typeof record !== "object") {
1259
1326
  return record;
1260
1327
  }
1261
1328
  if (Reflect.has(record, "__hybridId")) {
1262
- return Reflect.get(record, "__hybridId").value;
1329
+ return Reflect.get(record, "__hybridId");
1263
1330
  }
1264
1331
  return Reflect.get(record, table.value.keyName).value;
1265
1332
  }
@@ -1272,6 +1339,7 @@ function useTable(props, key, defaultOptions = {}) {
1272
1339
  url: route(table.value.endpoint),
1273
1340
  preserveState: true,
1274
1341
  data: {
1342
+ ...getAdditionnalData(),
1275
1343
  type: "action:inline",
1276
1344
  action: getActionName(action),
1277
1345
  tableId: table.value.id,
@@ -1292,6 +1360,7 @@ function useTable(props, key, defaultOptions = {}) {
1292
1360
  url: route(table.value.endpoint),
1293
1361
  preserveState: true,
1294
1362
  data: {
1363
+ ...getAdditionnalData(),
1295
1364
  type: "action:bulk",
1296
1365
  action: actionName,
1297
1366
  tableId: table.value.id,
@@ -1326,6 +1395,8 @@ function useTable(props, key, defaultOptions = {}) {
1326
1395
  allSelected: bulk.allSelected,
1327
1396
  /** The current record selection. */
1328
1397
  selection: bulk.selection,
1398
+ /** Binds a checkbox to its selection state. */
1399
+ bindCheckbox: (key2) => bulk.bindCheckbox(key2),
1329
1400
  /** Toggles selection for the given record. */
1330
1401
  toggle: (record) => bulk.toggle(getRecordKey(record)),
1331
1402
  /** Selects selection for the given record. */
@@ -1399,43 +1470,4 @@ function useTable(props, key, defaultOptions = {}) {
1399
1470
  });
1400
1471
  }
1401
1472
 
1402
- function useQueryParameters() {
1403
- const state = reactive({});
1404
- function updateState() {
1405
- const params = new URLSearchParams(window.location.search);
1406
- const unusedKeys = new Set(Object.keys(state));
1407
- for (const key of params.keys()) {
1408
- const paramsForKey = params.getAll(key);
1409
- state[key] = paramsForKey.length > 1 ? paramsForKey : params.get(key) || "";
1410
- unusedKeys.delete(key);
1411
- }
1412
- Array.from(unusedKeys).forEach((key) => delete state[key]);
1413
- }
1414
- updateState();
1415
- registerHook$1("after", updateState);
1416
- return state;
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
- }
1440
-
1441
1473
  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.13",
4
+ "version": "0.7.15",
5
5
  "description": "Vue adapter for Hybridly",
6
6
  "author": "Enzo Innocenzi <enzo@innocenzi.dev>",
7
7
  "license": "MIT",
@@ -43,22 +43,22 @@
43
43
  "vue": "^3.2.45"
44
44
  },
45
45
  "dependencies": {
46
- "@clickbar/dot-diver": "^1.0.6",
47
- "@vue/devtools-api": "^7.3.5",
46
+ "@clickbar/dot-diver": "^1.0.7",
47
+ "@vue/devtools-api": "^7.5.3",
48
48
  "defu": "^6.1.4",
49
49
  "lodash.isequal": "^4.5.0",
50
50
  "nprogress": "^0.2.0",
51
- "qs": "^6.12.1",
52
- "@hybridly/utils": "0.7.13",
53
- "@hybridly/core": "0.7.13"
51
+ "qs": "^6.13.0",
52
+ "@hybridly/core": "0.7.15",
53
+ "@hybridly/utils": "0.7.15"
54
54
  },
55
55
  "devDependencies": {
56
- "@types/lodash": "^4.17.6",
56
+ "@types/lodash": "^4.17.12",
57
57
  "@types/lodash.isequal": "^4.5.8",
58
58
  "@types/nprogress": "^0.2.3",
59
59
  "@vue/test-utils": "^2.4.6",
60
- "axios": "^1.7.2",
61
- "vue": "^3.4.31"
60
+ "axios": "^1.7.7",
61
+ "vue": "^3.5.12"
62
62
  },
63
63
  "scripts": {
64
64
  "build": "unbuild",