@vueuse/components 9.1.1 → 9.3.0

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
@@ -71,23 +71,21 @@ function onClickOutside(target, handler, options = {}) {
71
71
  const listener = (event) => {
72
72
  window.clearTimeout(fallback);
73
73
  const el = unrefElement(target);
74
- const composedPath = event.composedPath();
75
- if (!el || el === event.target || composedPath.includes(el) || !shouldListen.value)
74
+ if (!el || el === event.target || event.composedPath().includes(el) || !shouldListen.value)
76
75
  return;
77
- if (ignore && ignore.length > 0) {
78
- if (ignore.some((target2) => {
79
- const el2 = unrefElement(target2);
80
- return el2 && (event.target === el2 || composedPath.includes(el2));
81
- }))
82
- return;
83
- }
84
76
  handler(event);
85
77
  };
78
+ const shouldIgnore = (event) => {
79
+ return ignore && ignore.some((target2) => {
80
+ const el = unrefElement(target2);
81
+ return el && (event.target === el || event.composedPath().includes(el));
82
+ });
83
+ };
86
84
  const cleanup = [
87
85
  useEventListener(window, "click", listener, { passive: true, capture }),
88
86
  useEventListener(window, "pointerdown", (e) => {
89
87
  const el = unrefElement(target);
90
- shouldListen.value = !!el && !e.composedPath().includes(el);
88
+ shouldListen.value = !!el && !e.composedPath().includes(el) && !shouldIgnore(e);
91
89
  }, { passive: true }),
92
90
  useEventListener(window, "pointerup", (e) => {
93
91
  if (e.button === 0) {
@@ -107,18 +105,20 @@ function onClickOutside(target, handler, options = {}) {
107
105
  return stop;
108
106
  }
109
107
 
110
- const handler = () => {
111
- let stop = null;
112
- return (el, binding) => {
113
- if (stop) {
114
- stop();
115
- stop = onClickOutside(el, binding.value);
116
- return;
108
+ const vOnClickOutside = {
109
+ [shared.directiveHooks.mounted](el, binding) {
110
+ const capture = !binding.modifiers.bubble;
111
+ if (typeof binding.value === "function") {
112
+ el.__onClickOutside_stop = onClickOutside(el, binding.value, { capture });
113
+ } else {
114
+ const [handler, options] = binding.value;
115
+ el.__onClickOutside_stop = onClickOutside(el, handler, Object.assign({ capture }, options));
117
116
  }
118
- stop = onClickOutside(el, binding.value);
119
- };
117
+ },
118
+ [shared.directiveHooks.unmounted](el) {
119
+ el.__onClickOutside_stop();
120
+ }
120
121
  };
121
- const vOnClickOutside = handler();
122
122
 
123
123
  const createKeyPredicate = (keyFilter) => {
124
124
  if (typeof keyFilter === "function")
@@ -127,12 +127,29 @@ const createKeyPredicate = (keyFilter) => {
127
127
  return (event) => event.key === keyFilter;
128
128
  else if (Array.isArray(keyFilter))
129
129
  return (event) => keyFilter.includes(event.key);
130
- else if (keyFilter)
131
- return () => true;
132
- else
133
- return () => false;
130
+ return () => true;
134
131
  };
135
- function onKeyStroke(key, handler, options = {}) {
132
+ function onKeyStroke(...args) {
133
+ let key;
134
+ let handler;
135
+ let options = {};
136
+ if (args.length === 3) {
137
+ key = args[0];
138
+ handler = args[1];
139
+ options = args[2];
140
+ } else if (args.length === 2) {
141
+ if (typeof args[1] === "object") {
142
+ key = true;
143
+ handler = args[0];
144
+ options = args[1];
145
+ } else {
146
+ key = args[0];
147
+ handler = args[1];
148
+ }
149
+ } else {
150
+ key = true;
151
+ handler = args[0];
152
+ }
136
153
  const { target = defaultWindow, eventName = "keydown", passive = false } = options;
137
154
  const predicate = createKeyPredicate(key);
138
155
  const listener = (e) => {
@@ -161,7 +178,7 @@ var __spreadValues$d = (a, b) => {
161
178
  const vOnKeyStroke = {
162
179
  [shared.directiveHooks.mounted](el, binding) {
163
180
  var _a, _b;
164
- const keys = (_b = (_a = binding.arg) == null ? void 0 : _a.split(",")) != null ? _b : [];
181
+ const keys = (_b = (_a = binding.arg) == null ? void 0 : _a.split(",")) != null ? _b : true;
165
182
  if (typeof binding.value === "function") {
166
183
  onKeyStroke(keys, binding.value, {
167
184
  target: el
@@ -179,11 +196,11 @@ const DEFAULT_DELAY = 500;
179
196
  function onLongPress(target, handler, options) {
180
197
  var _a, _b;
181
198
  const elementRef = vueDemi.computed(() => unrefElement(target));
182
- let timeout = null;
199
+ let timeout;
183
200
  function clear() {
184
- if (timeout != null) {
201
+ if (timeout) {
185
202
  clearTimeout(timeout);
186
- timeout = null;
203
+ timeout = void 0;
187
204
  }
188
205
  }
189
206
  function onDown(ev) {
@@ -422,28 +439,27 @@ function useMediaQuery(query, options = {}) {
422
439
  const isSupported = useSupported(() => window && "matchMedia" in window && typeof window.matchMedia === "function");
423
440
  let mediaQuery;
424
441
  const matches = vueDemi.ref(false);
442
+ const cleanup = () => {
443
+ if (!mediaQuery)
444
+ return;
445
+ if ("removeEventListener" in mediaQuery)
446
+ mediaQuery.removeEventListener("change", update);
447
+ else
448
+ mediaQuery.removeListener(update);
449
+ };
425
450
  const update = () => {
426
451
  if (!isSupported.value)
427
452
  return;
428
- if (!mediaQuery)
429
- mediaQuery = window.matchMedia(query);
453
+ cleanup();
454
+ mediaQuery = window.matchMedia(shared.resolveRef(query).value);
430
455
  matches.value = mediaQuery.matches;
431
- };
432
- shared.tryOnBeforeMount(() => {
433
- update();
434
- if (!mediaQuery)
435
- return;
436
456
  if ("addEventListener" in mediaQuery)
437
457
  mediaQuery.addEventListener("change", update);
438
458
  else
439
459
  mediaQuery.addListener(update);
440
- shared.tryOnScopeDispose(() => {
441
- if ("removeEventListener" in mediaQuery)
442
- mediaQuery.removeEventListener("change", update);
443
- else
444
- mediaQuery.removeListener(update);
445
- });
446
- });
460
+ };
461
+ vueDemi.watchEffect(update);
462
+ shared.tryOnScopeDispose(() => cleanup());
447
463
  return matches;
448
464
  }
449
465
 
@@ -649,12 +665,18 @@ const UseDraggable = vueDemi.defineComponent({
649
665
  "preventDefault",
650
666
  "stopPropagation",
651
667
  "pointerTypes",
652
- "as"
668
+ "as",
669
+ "handle"
653
670
  ],
654
671
  setup(props, { slots }) {
655
672
  const target = vueDemi.ref();
673
+ const handle = vueDemi.computed(() => {
674
+ var _a;
675
+ return (_a = props.handle) != null ? _a : target.value;
676
+ });
656
677
  const initialValue = props.storageKey ? core.useStorage(props.storageKey, shared.resolveUnref(props.initialValue) || { x: 0, y: 0 }, core.isClient ? props.storageType === "session" ? sessionStorage : localStorage : void 0) : props.initialValue || { x: 0, y: 0 };
657
678
  const data = vueDemi.reactive(core.useDraggable(target, __spreadProps$8(__spreadValues$a({}, props), {
679
+ handle,
658
680
  initialValue
659
681
  })));
660
682
  return () => {
@@ -750,11 +772,18 @@ function useResizeObserver(target, callback, options = {}) {
750
772
  }
751
773
 
752
774
  function useElementSize(target, initialSize = { width: 0, height: 0 }, options = {}) {
775
+ const { box = "content-box" } = options;
753
776
  const width = vueDemi.ref(initialSize.width);
754
777
  const height = vueDemi.ref(initialSize.height);
755
778
  useResizeObserver(target, ([entry]) => {
756
- width.value = entry.contentRect.width;
757
- height.value = entry.contentRect.height;
779
+ const boxSize = box === "border-box" ? entry.borderBoxSize : box === "content-box" ? entry.contentBoxSize : entry.devicePixelContentBoxSize;
780
+ if (boxSize) {
781
+ width.value = boxSize.reduce((acc, { inlineSize }) => acc + inlineSize, 0);
782
+ height.value = boxSize.reduce((acc, { blockSize }) => acc + blockSize, 0);
783
+ } else {
784
+ width.value = entry.contentRect.width;
785
+ height.value = entry.contentRect.height;
786
+ }
758
787
  }, options);
759
788
  vueDemi.watch(() => unrefElement(target), (ele) => {
760
789
  width.value = ele ? initialSize.width : 0;
@@ -797,7 +826,7 @@ function useElementVisibility(element, { window = defaultWindow, scrollTarget }
797
826
  if (!window)
798
827
  return;
799
828
  const document = window.document;
800
- const el = shared.resolveUnref(element);
829
+ const el = unrefElement(element);
801
830
  if (!el) {
802
831
  elementIsVisible.value = false;
803
832
  } else {
@@ -805,9 +834,12 @@ function useElementVisibility(element, { window = defaultWindow, scrollTarget }
805
834
  elementIsVisible.value = rect.top <= (window.innerHeight || document.documentElement.clientHeight) && rect.left <= (window.innerWidth || document.documentElement.clientWidth) && rect.bottom >= 0 && rect.right >= 0;
806
835
  }
807
836
  };
808
- shared.tryOnMounted(testBounding);
837
+ vueDemi.watch(() => unrefElement(element), () => testBounding(), { immediate: true, flush: "post" });
809
838
  if (window) {
810
- shared.tryOnMounted(() => useEventListener(() => shared.resolveUnref(scrollTarget) || window, "scroll", testBounding, { capture: false, passive: true }));
839
+ useEventListener(scrollTarget || window, "scroll", testBounding, {
840
+ capture: false,
841
+ passive: true
842
+ });
811
843
  }
812
844
  return elementIsVisible;
813
845
  }
@@ -999,10 +1031,38 @@ function useScroll(element, options = {}) {
999
1031
  eventListenerOptions = {
1000
1032
  capture: false,
1001
1033
  passive: true
1002
- }
1034
+ },
1035
+ behavior = "auto"
1003
1036
  } = options;
1004
- const x = vueDemi.ref(0);
1005
- const y = vueDemi.ref(0);
1037
+ const internalX = vueDemi.ref(0);
1038
+ const internalY = vueDemi.ref(0);
1039
+ const x = vueDemi.computed({
1040
+ get() {
1041
+ return internalX.value;
1042
+ },
1043
+ set(x2) {
1044
+ scrollTo(x2, void 0);
1045
+ }
1046
+ });
1047
+ const y = vueDemi.computed({
1048
+ get() {
1049
+ return internalY.value;
1050
+ },
1051
+ set(y2) {
1052
+ scrollTo(void 0, y2);
1053
+ }
1054
+ });
1055
+ function scrollTo(_x, _y) {
1056
+ var _a, _b, _c;
1057
+ const _element = shared.resolveUnref(element);
1058
+ if (!_element)
1059
+ return;
1060
+ (_c = _element instanceof Document ? document.body : _element) == null ? void 0 : _c.scrollTo({
1061
+ top: (_a = shared.resolveUnref(_y)) != null ? _a : y.value,
1062
+ left: (_b = shared.resolveUnref(_x)) != null ? _b : x.value,
1063
+ behavior: shared.resolveUnref(behavior)
1064
+ });
1065
+ }
1006
1066
  const isScrolling = vueDemi.ref(false);
1007
1067
  const arrivedState = vueDemi.reactive({
1008
1068
  left: true,
@@ -1027,19 +1087,19 @@ function useScroll(element, options = {}) {
1027
1087
  const onScrollHandler = (e) => {
1028
1088
  const eventTarget = e.target === document ? e.target.documentElement : e.target;
1029
1089
  const scrollLeft = eventTarget.scrollLeft;
1030
- directions.left = scrollLeft < x.value;
1031
- directions.right = scrollLeft > x.value;
1090
+ directions.left = scrollLeft < internalX.value;
1091
+ directions.right = scrollLeft > internalY.value;
1032
1092
  arrivedState.left = scrollLeft <= 0 + (offset.left || 0);
1033
1093
  arrivedState.right = scrollLeft + eventTarget.clientWidth >= eventTarget.scrollWidth - (offset.right || 0) - ARRIVED_STATE_THRESHOLD_PIXELS;
1034
- x.value = scrollLeft;
1094
+ internalX.value = scrollLeft;
1035
1095
  let scrollTop = eventTarget.scrollTop;
1036
1096
  if (e.target === document && !scrollTop)
1037
1097
  scrollTop = document.body.scrollTop;
1038
- directions.top = scrollTop < y.value;
1039
- directions.bottom = scrollTop > y.value;
1098
+ directions.top = scrollTop < internalY.value;
1099
+ directions.bottom = scrollTop > internalY.value;
1040
1100
  arrivedState.top = scrollTop <= 0 + (offset.top || 0);
1041
1101
  arrivedState.bottom = scrollTop + eventTarget.clientHeight >= eventTarget.scrollHeight - (offset.bottom || 0) - ARRIVED_STATE_THRESHOLD_PIXELS;
1042
- y.value = scrollTop;
1102
+ internalY.value = scrollTop;
1043
1103
  isScrolling.value = true;
1044
1104
  onScrollEnd(e);
1045
1105
  onScroll(e);