@vueuse/components 10.0.0-beta.1 → 10.0.0-beta.3

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/index.cjs CHANGED
@@ -54,14 +54,20 @@ function useEventListener(...args) {
54
54
  el.addEventListener(event, listener, options2);
55
55
  return () => el.removeEventListener(event, listener, options2);
56
56
  };
57
- const stopWatch = vueDemi.watch(() => [unrefElement(target), shared.resolveUnref(options)], ([el, options2]) => {
58
- cleanup();
59
- if (!el)
60
- return;
61
- cleanups.push(...events.flatMap((event) => {
62
- return listeners.map((listener) => register(el, event, listener, options2));
63
- }));
64
- }, { immediate: true, flush: "post" });
57
+ const stopWatch = vueDemi.watch(
58
+ () => [unrefElement(target), shared.resolveUnref(options)],
59
+ ([el, options2]) => {
60
+ cleanup();
61
+ if (!el)
62
+ return;
63
+ cleanups.push(
64
+ ...events.flatMap((event) => {
65
+ return listeners.map((listener) => register(el, event, listener, options2));
66
+ })
67
+ );
68
+ },
69
+ { immediate: true, flush: "post" }
70
+ );
65
71
  const stop = () => {
66
72
  stopWatch();
67
73
  cleanup();
@@ -135,7 +141,7 @@ const vOnClickOutside = {
135
141
  }
136
142
  };
137
143
 
138
- const createKeyPredicate = (keyFilter) => {
144
+ function createKeyPredicate(keyFilter) {
139
145
  if (typeof keyFilter === "function")
140
146
  return keyFilter;
141
147
  else if (typeof keyFilter === "string")
@@ -143,7 +149,7 @@ const createKeyPredicate = (keyFilter) => {
143
149
  else if (Array.isArray(keyFilter))
144
150
  return (event) => keyFilter.includes(event.key);
145
151
  return () => true;
146
- };
152
+ }
147
153
  function onKeyStroke(...args) {
148
154
  let key;
149
155
  let handler;
@@ -165,9 +171,16 @@ function onKeyStroke(...args) {
165
171
  key = true;
166
172
  handler = args[0];
167
173
  }
168
- const { target = defaultWindow, eventName = "keydown", passive = false } = options;
174
+ const {
175
+ target = defaultWindow,
176
+ eventName = "keydown",
177
+ passive = false,
178
+ dedupe = false
179
+ } = options;
169
180
  const predicate = createKeyPredicate(key);
170
181
  const listener = (e) => {
182
+ if (e.repeat && shared.resolveUnref(dedupe))
183
+ return;
171
184
  if (predicate(e))
172
185
  handler(e);
173
186
  };
@@ -227,7 +240,10 @@ function onLongPress(target, handler, options) {
227
240
  ev.preventDefault();
228
241
  if ((_c = options == null ? void 0 : options.modifiers) == null ? void 0 : _c.stop)
229
242
  ev.stopPropagation();
230
- timeout = setTimeout(() => handler(ev), (_d = options == null ? void 0 : options.delay) != null ? _d : DEFAULT_DELAY);
243
+ timeout = setTimeout(
244
+ () => handler(ev),
245
+ (_d = options == null ? void 0 : options.delay) != null ? _d : DEFAULT_DELAY
246
+ );
231
247
  }
232
248
  const listenerOptions = {
233
249
  capture: (_a = options == null ? void 0 : options.modifiers) == null ? void 0 : _a.capture,
@@ -244,9 +260,13 @@ const OnLongPress = /* @__PURE__ */ /* #__PURE__ */ vueDemi.defineComponent({
244
260
  emits: ["trigger"],
245
261
  setup(props, { slots, emit }) {
246
262
  const target = vueDemi.ref();
247
- onLongPress(target, (e) => {
248
- emit("trigger", e);
249
- }, props.options);
263
+ onLongPress(
264
+ target,
265
+ (e) => {
266
+ emit("trigger", e);
267
+ },
268
+ props.options
269
+ );
250
270
  return () => {
251
271
  if (slots.default)
252
272
  return vueDemi.h(props.as || "div", { ref: target }, slots.default());
@@ -392,7 +412,11 @@ function useStorage(key, defaults, storage, options = {}) {
392
412
  const rawInit = shared.resolveUnref(defaults);
393
413
  const type = guessSerializerType(rawInit);
394
414
  const serializer = (_a = options.serializer) != null ? _a : StorageSerializers[type];
395
- const { pause: pauseWatch, resume: resumeWatch } = shared.pausableWatch(data, () => write(data.value), { flush, deep, eventFilter });
415
+ const { pause: pauseWatch, resume: resumeWatch } = shared.pausableWatch(
416
+ data,
417
+ () => write(data.value),
418
+ { flush, deep, eventFilter }
419
+ );
396
420
  if (window && listenToStorageChanges) {
397
421
  useEventListener(window, "storage", update);
398
422
  useEventListener(window, customStorageEventName, updateFromCustomEvent);
@@ -469,12 +493,22 @@ function useStorage(key, defaults, storage, options = {}) {
469
493
  }
470
494
  }
471
495
 
472
- function useSupported(callback, sync = false) {
473
- const isSupported = vueDemi.ref();
474
- const update = () => isSupported.value = Boolean(callback());
475
- update();
476
- shared.tryOnMounted(update, sync);
477
- return isSupported;
496
+ function useMounted() {
497
+ const isMounted = vueDemi.ref(false);
498
+ if (vueDemi.getCurrentInstance()) {
499
+ vueDemi.onMounted(() => {
500
+ isMounted.value = true;
501
+ });
502
+ }
503
+ return isMounted;
504
+ }
505
+
506
+ function useSupported(callback) {
507
+ const isMounted = useMounted();
508
+ return vueDemi.computed(() => {
509
+ isMounted.value;
510
+ return Boolean(callback());
511
+ });
478
512
  }
479
513
 
480
514
  function useMediaQuery(query, options = {}) {
@@ -495,7 +529,9 @@ function useMediaQuery(query, options = {}) {
495
529
  return;
496
530
  cleanup();
497
531
  mediaQuery = window.matchMedia(shared.resolveRef(query).value);
498
- matches.value = mediaQuery.matches;
532
+ matches.value = !!(mediaQuery == null ? void 0 : mediaQuery.matches);
533
+ if (!mediaQuery)
534
+ return;
499
535
  if ("addEventListener" in mediaQuery)
500
536
  mediaQuery.addEventListener("change", update);
501
537
  else
@@ -537,6 +573,7 @@ function useColorMode(options = {}) {
537
573
  listenToStorageChanges = true,
538
574
  storageRef,
539
575
  emitAuto,
576
+ // TODO: switch to true in v10
540
577
  disableTransition = false
541
578
  } = options;
542
579
  const modes = __spreadValues$b({
@@ -555,33 +592,36 @@ function useColorMode(options = {}) {
555
592
  store.value = v;
556
593
  }
557
594
  });
558
- const updateHTMLAttrs = getSSRHandler("updateHTMLAttrs", (selector2, attribute2, value) => {
559
- const el = window == null ? void 0 : window.document.querySelector(selector2);
560
- if (!el)
561
- return;
562
- let style;
563
- if (disableTransition) {
564
- style = window.document.createElement("style");
565
- style.type = "text/css";
566
- style.appendChild(document.createTextNode("*{-webkit-transition:none!important;-moz-transition:none!important;-o-transition:none!important;-ms-transition:none!important;transition:none!important}"));
567
- window.document.head.appendChild(style);
568
- }
569
- if (attribute2 === "class") {
570
- const current = value.split(/\s/g);
571
- Object.values(modes).flatMap((i) => (i || "").split(/\s/g)).filter(Boolean).forEach((v) => {
572
- if (current.includes(v))
573
- el.classList.add(v);
574
- else
575
- el.classList.remove(v);
576
- });
577
- } else {
578
- el.setAttribute(attribute2, value);
579
- }
580
- if (disableTransition) {
581
- window.getComputedStyle(style).opacity;
582
- document.head.removeChild(style);
595
+ const updateHTMLAttrs = getSSRHandler(
596
+ "updateHTMLAttrs",
597
+ (selector2, attribute2, value) => {
598
+ const el = window == null ? void 0 : window.document.querySelector(selector2);
599
+ if (!el)
600
+ return;
601
+ let style;
602
+ if (disableTransition) {
603
+ style = window.document.createElement("style");
604
+ style.type = "text/css";
605
+ style.appendChild(document.createTextNode("*{-webkit-transition:none!important;-moz-transition:none!important;-o-transition:none!important;-ms-transition:none!important;transition:none!important}"));
606
+ window.document.head.appendChild(style);
607
+ }
608
+ if (attribute2 === "class") {
609
+ const current = value.split(/\s/g);
610
+ Object.values(modes).flatMap((i) => (i || "").split(/\s/g)).filter(Boolean).forEach((v) => {
611
+ if (current.includes(v))
612
+ el.classList.add(v);
613
+ else
614
+ el.classList.remove(v);
615
+ });
616
+ } else {
617
+ el.setAttribute(attribute2, value);
618
+ }
619
+ if (disableTransition) {
620
+ window.getComputedStyle(style).opacity;
621
+ document.head.removeChild(style);
622
+ }
583
623
  }
584
- });
624
+ );
585
625
  function defaultOnChanged(mode) {
586
626
  var _a;
587
627
  const resolvedMode = mode === "auto" ? preferredMode.value : mode;
@@ -721,7 +761,8 @@ const UseDraggable = /* @__PURE__ */ /* #__PURE__ */ vueDemi.defineComponent({
721
761
  "stopPropagation",
722
762
  "pointerTypes",
723
763
  "as",
724
- "handle"
764
+ "handle",
765
+ "axis"
725
766
  ],
726
767
  setup(props, { slots }) {
727
768
  const target = vueDemi.ref();
@@ -729,7 +770,11 @@ const UseDraggable = /* @__PURE__ */ /* #__PURE__ */ vueDemi.defineComponent({
729
770
  var _a;
730
771
  return (_a = props.handle) != null ? _a : target.value;
731
772
  });
732
- const storageValue = props.storageKey && core.useStorage(props.storageKey, shared.resolveUnref(props.initialValue) || { x: 0, y: 0 }, core.isClient ? props.storageType === "session" ? sessionStorage : localStorage : void 0);
773
+ const storageValue = props.storageKey && core.useStorage(
774
+ props.storageKey,
775
+ shared.resolveUnref(props.initialValue) || { x: 0, y: 0 },
776
+ core.isClient ? props.storageType === "session" ? sessionStorage : localStorage : void 0
777
+ );
733
778
  const initialValue = storageValue || props.initialValue || { x: 0, y: 0 };
734
779
  const onEnd = (position) => {
735
780
  if (!storageValue)
@@ -835,13 +880,21 @@ function useResizeObserver(target, callback, options = {}) {
835
880
  observer = void 0;
836
881
  }
837
882
  };
838
- const stopWatch = vueDemi.watch(() => unrefElement(target), (el) => {
839
- cleanup();
840
- if (isSupported.value && window && el) {
841
- observer = new ResizeObserver(callback);
842
- observer.observe(el, observerOptions);
843
- }
844
- }, { immediate: true, flush: "post" });
883
+ const targets = vueDemi.computed(
884
+ () => Array.isArray(target) ? target.map((el) => unrefElement(el)) : [unrefElement(target)]
885
+ );
886
+ const stopWatch = vueDemi.watch(
887
+ targets,
888
+ (els) => {
889
+ cleanup();
890
+ if (isSupported.value && window) {
891
+ observer = new ResizeObserver(callback);
892
+ for (const _el of els)
893
+ _el && observer.observe(_el, observerOptions);
894
+ }
895
+ },
896
+ { immediate: true, flush: "post", deep: true }
897
+ );
845
898
  const stop = () => {
846
899
  cleanup();
847
900
  stopWatch();
@@ -861,30 +914,37 @@ function useElementSize(target, initialSize = { width: 0, height: 0 }, options =
861
914
  });
862
915
  const width = vueDemi.ref(initialSize.width);
863
916
  const height = vueDemi.ref(initialSize.height);
864
- useResizeObserver(target, ([entry]) => {
865
- const boxSize = box === "border-box" ? entry.borderBoxSize : box === "content-box" ? entry.contentBoxSize : entry.devicePixelContentBoxSize;
866
- if (window && isSVG.value) {
867
- const $elem = unrefElement(target);
868
- if ($elem) {
869
- const styles = window.getComputedStyle($elem);
870
- width.value = parseFloat(styles.width);
871
- height.value = parseFloat(styles.height);
872
- }
873
- } else {
874
- if (boxSize) {
875
- const formatBoxSize = Array.isArray(boxSize) ? boxSize : [boxSize];
876
- width.value = formatBoxSize.reduce((acc, { inlineSize }) => acc + inlineSize, 0);
877
- height.value = formatBoxSize.reduce((acc, { blockSize }) => acc + blockSize, 0);
917
+ useResizeObserver(
918
+ target,
919
+ ([entry]) => {
920
+ const boxSize = box === "border-box" ? entry.borderBoxSize : box === "content-box" ? entry.contentBoxSize : entry.devicePixelContentBoxSize;
921
+ if (window && isSVG.value) {
922
+ const $elem = unrefElement(target);
923
+ if ($elem) {
924
+ const styles = window.getComputedStyle($elem);
925
+ width.value = parseFloat(styles.width);
926
+ height.value = parseFloat(styles.height);
927
+ }
878
928
  } else {
879
- width.value = entry.contentRect.width;
880
- height.value = entry.contentRect.height;
929
+ if (boxSize) {
930
+ const formatBoxSize = Array.isArray(boxSize) ? boxSize : [boxSize];
931
+ width.value = formatBoxSize.reduce((acc, { inlineSize }) => acc + inlineSize, 0);
932
+ height.value = formatBoxSize.reduce((acc, { blockSize }) => acc + blockSize, 0);
933
+ } else {
934
+ width.value = entry.contentRect.width;
935
+ height.value = entry.contentRect.height;
936
+ }
881
937
  }
938
+ },
939
+ options
940
+ );
941
+ vueDemi.watch(
942
+ () => unrefElement(target),
943
+ (ele) => {
944
+ width.value = ele ? initialSize.width : 0;
945
+ height.value = ele ? initialSize.height : 0;
882
946
  }
883
- }, options);
884
- vueDemi.watch(() => unrefElement(target), (ele) => {
885
- width.value = ele ? initialSize.width : 0;
886
- height.value = ele ? initialSize.height : 0;
887
- });
947
+ );
888
948
  return {
889
949
  width,
890
950
  height
@@ -916,27 +976,63 @@ const UseElementVisibility = /* @__PURE__ */ /* #__PURE__ */ vueDemi.defineCompo
916
976
  }
917
977
  });
918
978
 
979
+ function useIntersectionObserver(target, callback, options = {}) {
980
+ const {
981
+ root,
982
+ rootMargin = "0px",
983
+ threshold = 0.1,
984
+ window = defaultWindow
985
+ } = options;
986
+ const isSupported = useSupported(() => window && "IntersectionObserver" in window);
987
+ let cleanup = shared.noop;
988
+ const stopWatch = isSupported.value ? vueDemi.watch(
989
+ () => ({
990
+ el: unrefElement(target),
991
+ root: unrefElement(root)
992
+ }),
993
+ ({ el, root: root2 }) => {
994
+ cleanup();
995
+ if (!el)
996
+ return;
997
+ const observer = new IntersectionObserver(
998
+ callback,
999
+ {
1000
+ root: root2,
1001
+ rootMargin,
1002
+ threshold
1003
+ }
1004
+ );
1005
+ observer.observe(el);
1006
+ cleanup = () => {
1007
+ observer.disconnect();
1008
+ cleanup = shared.noop;
1009
+ };
1010
+ },
1011
+ { immediate: true, flush: "post" }
1012
+ ) : shared.noop;
1013
+ const stop = () => {
1014
+ cleanup();
1015
+ stopWatch();
1016
+ };
1017
+ shared.tryOnScopeDispose(stop);
1018
+ return {
1019
+ isSupported,
1020
+ stop
1021
+ };
1022
+ }
1023
+
919
1024
  function useElementVisibility(element, { window = defaultWindow, scrollTarget } = {}) {
920
1025
  const elementIsVisible = vueDemi.ref(false);
921
- const testBounding = () => {
922
- if (!window)
923
- return;
924
- const document = window.document;
925
- const el = unrefElement(element);
926
- if (!el) {
927
- elementIsVisible.value = false;
928
- } else {
929
- const rect = el.getBoundingClientRect();
930
- elementIsVisible.value = rect.top <= (window.innerHeight || document.documentElement.clientHeight) && rect.left <= (window.innerWidth || document.documentElement.clientWidth) && rect.bottom >= 0 && rect.right >= 0;
1026
+ useIntersectionObserver(
1027
+ element,
1028
+ ([{ isIntersecting }]) => {
1029
+ elementIsVisible.value = isIntersecting;
1030
+ },
1031
+ {
1032
+ root: scrollTarget,
1033
+ window
931
1034
  }
932
- };
933
- vueDemi.watch(() => unrefElement(element), () => testBounding(), { immediate: true, flush: "post" });
934
- if (window) {
935
- useEventListener(scrollTarget || window, "scroll", testBounding, {
936
- capture: false,
937
- passive: true
938
- });
939
- }
1035
+ );
940
1036
  return elementIsVisible;
941
1037
  }
942
1038
 
@@ -1083,13 +1179,21 @@ async function loadImage(options) {
1083
1179
  img.onerror = reject;
1084
1180
  });
1085
1181
  }
1086
- const useImage = (options, asyncStateOptions = {}) => {
1087
- const state = useAsyncState(() => loadImage(shared.resolveUnref(options)), void 0, __spreadValues$9({
1088
- resetOnExecute: true
1089
- }, asyncStateOptions));
1090
- vueDemi.watch(() => shared.resolveUnref(options), () => state.execute(asyncStateOptions.delay), { deep: true });
1182
+ function useImage(options, asyncStateOptions = {}) {
1183
+ const state = useAsyncState(
1184
+ () => loadImage(shared.resolveUnref(options)),
1185
+ void 0,
1186
+ __spreadValues$9({
1187
+ resetOnExecute: true
1188
+ }, asyncStateOptions)
1189
+ );
1190
+ vueDemi.watch(
1191
+ () => shared.resolveUnref(options),
1192
+ () => state.execute(asyncStateOptions.delay),
1193
+ { deep: true }
1194
+ );
1091
1195
  return state;
1092
- };
1196
+ }
1093
1197
 
1094
1198
  const UseImage = /* @__PURE__ */ /* #__PURE__ */ vueDemi.defineComponent({
1095
1199
  name: "UseImage",
@@ -1205,8 +1309,18 @@ function useScroll(element, options = {}) {
1205
1309
  onScrollEndDebounced(e);
1206
1310
  onScroll(e);
1207
1311
  };
1208
- useEventListener(element, "scroll", throttle ? shared.useThrottleFn(onScrollHandler, throttle, true, false) : onScrollHandler, eventListenerOptions);
1209
- useEventListener(element, "scrollend", onScrollEnd, eventListenerOptions);
1312
+ useEventListener(
1313
+ element,
1314
+ "scroll",
1315
+ throttle ? shared.useThrottleFn(onScrollHandler, throttle, true, false) : onScrollHandler,
1316
+ eventListenerOptions
1317
+ );
1318
+ useEventListener(
1319
+ element,
1320
+ "scrollend",
1321
+ onScrollEnd,
1322
+ eventListenerOptions
1323
+ );
1210
1324
  return {
1211
1325
  x,
1212
1326
  y,
@@ -1238,30 +1352,36 @@ var __spreadProps$7 = (a, b) => __defProps$7(a, __getOwnPropDescs$7(b));
1238
1352
  function useInfiniteScroll(element, onLoadMore, options = {}) {
1239
1353
  var _a, _b;
1240
1354
  const direction = (_a = options.direction) != null ? _a : "bottom";
1241
- const state = vueDemi.reactive(useScroll(element, __spreadProps$7(__spreadValues$8({}, options), {
1242
- offset: __spreadValues$8({
1243
- [direction]: (_b = options.distance) != null ? _b : 0
1244
- }, options.offset)
1245
- })));
1246
- vueDemi.watch(() => state.arrivedState[direction], async (v) => {
1247
- var _a2, _b2;
1248
- if (v) {
1249
- const elem = shared.resolveUnref(element);
1250
- const previous = {
1251
- height: (_a2 = elem == null ? void 0 : elem.scrollHeight) != null ? _a2 : 0,
1252
- width: (_b2 = elem == null ? void 0 : elem.scrollWidth) != null ? _b2 : 0
1253
- };
1254
- await onLoadMore(state);
1255
- if (options.preserveScrollPosition && elem) {
1256
- vueDemi.nextTick(() => {
1257
- elem.scrollTo({
1258
- top: elem.scrollHeight - previous.height,
1259
- left: elem.scrollWidth - previous.width
1355
+ const state = vueDemi.reactive(useScroll(
1356
+ element,
1357
+ __spreadProps$7(__spreadValues$8({}, options), {
1358
+ offset: __spreadValues$8({
1359
+ [direction]: (_b = options.distance) != null ? _b : 0
1360
+ }, options.offset)
1361
+ })
1362
+ ));
1363
+ vueDemi.watch(
1364
+ () => state.arrivedState[direction],
1365
+ async (v) => {
1366
+ var _a2, _b2;
1367
+ if (v) {
1368
+ const elem = shared.resolveUnref(element);
1369
+ const previous = {
1370
+ height: (_a2 = elem == null ? void 0 : elem.scrollHeight) != null ? _a2 : 0,
1371
+ width: (_b2 = elem == null ? void 0 : elem.scrollWidth) != null ? _b2 : 0
1372
+ };
1373
+ await onLoadMore(state);
1374
+ if (options.preserveScrollPosition && elem) {
1375
+ vueDemi.nextTick(() => {
1376
+ elem.scrollTo({
1377
+ top: elem.scrollHeight - previous.height,
1378
+ left: elem.scrollWidth - previous.width
1379
+ });
1260
1380
  });
1261
- });
1381
+ }
1262
1382
  }
1263
1383
  }
1264
- });
1384
+ );
1265
1385
  }
1266
1386
 
1267
1387
  const vInfiniteScroll = {
@@ -1273,44 +1393,6 @@ const vInfiniteScroll = {
1273
1393
  }
1274
1394
  };
1275
1395
 
1276
- function useIntersectionObserver(target, callback, options = {}) {
1277
- const {
1278
- root,
1279
- rootMargin = "0px",
1280
- threshold = 0.1,
1281
- window = defaultWindow
1282
- } = options;
1283
- const isSupported = useSupported(() => window && "IntersectionObserver" in window);
1284
- let cleanup = shared.noop;
1285
- const stopWatch = isSupported.value ? vueDemi.watch(() => ({
1286
- el: unrefElement(target),
1287
- root: unrefElement(root)
1288
- }), ({ el, root: root2 }) => {
1289
- cleanup();
1290
- if (!el)
1291
- return;
1292
- const observer = new IntersectionObserver(callback, {
1293
- root: root2,
1294
- rootMargin,
1295
- threshold
1296
- });
1297
- observer.observe(el);
1298
- cleanup = () => {
1299
- observer.disconnect();
1300
- cleanup = shared.noop;
1301
- };
1302
- }, { immediate: true, flush: "post" }) : shared.noop;
1303
- const stop = () => {
1304
- cleanup();
1305
- stopWatch();
1306
- };
1307
- shared.tryOnScopeDispose(stop);
1308
- return {
1309
- isSupported,
1310
- stop
1311
- };
1312
- }
1313
-
1314
1396
  const vIntersectionObserver = {
1315
1397
  [shared.directiveHooks.mounted](el, binding) {
1316
1398
  if (typeof binding.value === "function")
@@ -1657,12 +1739,19 @@ function useCssVar(prop, target, options = {}) {
1657
1739
  window
1658
1740
  });
1659
1741
  }
1660
- vueDemi.watch([elRef, () => shared.resolveUnref(prop)], updateCssVar, { immediate: true });
1661
- vueDemi.watch(variable, (val) => {
1662
- var _a;
1663
- if ((_a = elRef.value) == null ? void 0 : _a.style)
1664
- elRef.value.style.setProperty(shared.resolveUnref(prop), val);
1665
- });
1742
+ vueDemi.watch(
1743
+ [elRef, () => shared.resolveUnref(prop)],
1744
+ updateCssVar,
1745
+ { immediate: true }
1746
+ );
1747
+ vueDemi.watch(
1748
+ variable,
1749
+ (val) => {
1750
+ var _a;
1751
+ if ((_a = elRef.value) == null ? void 0 : _a.style)
1752
+ elRef.value.style.setProperty(shared.resolveUnref(prop), val);
1753
+ }
1754
+ );
1666
1755
  return variable;
1667
1756
  }
1668
1757
 
@@ -1829,9 +1918,14 @@ function useScrollLock(element, initialState = false) {
1829
1918
  if (!ele || isLocked.value)
1830
1919
  return;
1831
1920
  if (shared.isIOS) {
1832
- stopTouchMoveListener = useEventListener(ele, "touchmove", (e) => {
1833
- preventDefault(e);
1834
- }, { passive: false });
1921
+ stopTouchMoveListener = useEventListener(
1922
+ ele,
1923
+ "touchmove",
1924
+ (e) => {
1925
+ preventDefault(e);
1926
+ },
1927
+ { passive: false }
1928
+ );
1835
1929
  }
1836
1930
  ele.style.overflow = "hidden";
1837
1931
  isLocked.value = true;
@@ -1858,7 +1952,7 @@ function useScrollLock(element, initialState = false) {
1858
1952
  });
1859
1953
  }
1860
1954
 
1861
- const onScrollLock = () => {
1955
+ function onScrollLock() {
1862
1956
  let isMounted = false;
1863
1957
  const state = vueDemi.ref(false);
1864
1958
  return (el, binding) => {
@@ -1869,7 +1963,7 @@ const onScrollLock = () => {
1869
1963
  const isLocked = useScrollLock(el, binding.value);
1870
1964
  vueDemi.watch(state, (v) => isLocked.value = v);
1871
1965
  };
1872
- };
1966
+ }
1873
1967
  const vScrollLock = onScrollLock();
1874
1968
 
1875
1969
  var __defProp$2 = Object.defineProperty;
@@ -1962,9 +2056,21 @@ const UseVirtualList = /* @__PURE__ */ /* #__PURE__ */ vueDemi.defineComponent({
1962
2056
  const { list, containerProps, wrapperProps, scrollTo } = core.useVirtualList(listRef, props.options);
1963
2057
  expose({ scrollTo });
1964
2058
  typeof containerProps.style === "object" && !Array.isArray(containerProps.style) && (containerProps.style.height = props.height || "300px");
1965
- return () => vueDemi.h("div", __spreadValues({}, containerProps), [
1966
- vueDemi.h("div", __spreadValues({}, wrapperProps.value), list.value.map((item) => vueDemi.h("div", { style: { overFlow: "hidden", height: item.height } }, slots.default ? slots.default(item) : "Please set content!")))
1967
- ]);
2059
+ return () => vueDemi.h(
2060
+ "div",
2061
+ __spreadValues({}, containerProps),
2062
+ [
2063
+ vueDemi.h(
2064
+ "div",
2065
+ __spreadValues({}, wrapperProps.value),
2066
+ list.value.map((item) => vueDemi.h(
2067
+ "div",
2068
+ { style: { overFlow: "hidden", height: item.height } },
2069
+ slots.default ? slots.default(item) : "Please set content!"
2070
+ ))
2071
+ )
2072
+ ]
2073
+ );
1968
2074
  }
1969
2075
  });
1970
2076
 
package/index.d.ts CHANGED
@@ -55,6 +55,12 @@ interface OnKeyStrokeOptions {
55
55
  eventName?: KeyStrokeEventName;
56
56
  target?: MaybeComputedRef<EventTarget | null | undefined>;
57
57
  passive?: boolean;
58
+ /**
59
+ * Set to `true` to ignore repeated events when the key is being held down.
60
+ *
61
+ * @default false
62
+ */
63
+ dedupe?: MaybeComputedRef<boolean>;
58
64
  }
59
65
 
60
66
  type BindingValueFunction$7 = (event: KeyboardEvent) => void;
@@ -451,7 +457,7 @@ interface UseIntersectionObserverOptions extends ConfigurableWindow {
451
457
  /**
452
458
  * The Element or Document whose bounds are used as the bounding box when testing for intersection.
453
459
  */
454
- root?: MaybeElementRef;
460
+ root?: MaybeComputedElementRef;
455
461
  /**
456
462
  * A string which specifies a set of offsets to add to the root's bounding_box when calculating intersections.
457
463
  */