@mantine-vue/hooks 3.5.0 → 3.6.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/cjs/index.cjs CHANGED
@@ -118,9 +118,10 @@ function useDebouncedCallback(callback, waitOrOptions) {
118
118
  }
119
119
  //#endregion
120
120
  //#region src/use-click-outside/use-click-outside.ts
121
- function useClickOutside(callback, events = ["mousedown", "touchstart"], nodes, enabled = true) {
121
+ function useClickOutside(callback, events = ["mousedown", "touchstart"], nodes, enabled = true, capture = false) {
122
122
  const element = (0, vue.ref)(null);
123
123
  let activeEvents = [];
124
+ let activeCapture = false;
124
125
  const listener = (event) => {
125
126
  const target = event.target;
126
127
  if (!target || !document.body.contains(target) && target.tagName !== "HTML") return;
@@ -131,17 +132,22 @@ function useClickOutside(callback, events = ["mousedown", "touchstart"], nodes,
131
132
  } else if (element.value && !path.includes(element.value)) callback(event);
132
133
  };
133
134
  const cleanup = () => {
134
- activeEvents.forEach((event) => document.removeEventListener(event, listener));
135
+ activeEvents.forEach((event) => document.removeEventListener(event, listener, activeCapture));
135
136
  activeEvents = [];
136
137
  };
137
138
  const bind = () => {
138
139
  cleanup();
139
140
  if (!(0, vue.toValue)(enabled)) return;
140
141
  activeEvents = (0, vue.toValue)(events) || ["mousedown", "touchstart"];
141
- activeEvents.forEach((event) => document.addEventListener(event, listener));
142
+ activeCapture = (0, vue.toValue)(capture);
143
+ activeEvents.forEach((event) => document.addEventListener(event, listener, activeCapture));
142
144
  };
143
145
  (0, vue.onMounted)(bind);
144
- (0, vue.watch)([() => (0, vue.toValue)(events)?.join(","), () => (0, vue.toValue)(enabled)], bind);
146
+ (0, vue.watch)([
147
+ () => (0, vue.toValue)(events)?.join(","),
148
+ () => (0, vue.toValue)(enabled),
149
+ () => (0, vue.toValue)(capture)
150
+ ], bind);
145
151
  (0, vue.onBeforeUnmount)(cleanup);
146
152
  return element;
147
153
  }
@@ -185,7 +191,11 @@ function useClipboard({ timeout = 2e3 } = {}) {
185
191
  //#region src/use-media-query/use-media-query.ts
186
192
  function getInitialMediaQueryValue(query, initialValue) {
187
193
  if (typeof initialValue === "boolean") return initialValue;
188
- if (typeof window !== "undefined" && typeof window.matchMedia === "function") return window.matchMedia(query).matches;
194
+ if (typeof window !== "undefined" && typeof window.matchMedia === "function") try {
195
+ return window.matchMedia(query).matches;
196
+ } catch {
197
+ return false;
198
+ }
189
199
  return false;
190
200
  }
191
201
  function useMediaQuery(query, initialValue = false, options = { getInitialValueInEffect: true }) {
@@ -255,6 +265,10 @@ function useDebouncedState(initialValue, wait, options = {}) {
255
265
  if (options.leading && !leadingCalled) {
256
266
  value.value = next;
257
267
  leadingCalled = true;
268
+ clear();
269
+ timeout = setTimeout(() => {
270
+ leadingCalled = false;
271
+ }, wait);
258
272
  } else {
259
273
  clear();
260
274
  timeout = setTimeout(() => {
@@ -1026,7 +1040,7 @@ function usePagination({ total, siblings = 1, boundaries = 1, page, initialPage,
1026
1040
  const leftSiblingIndex = Math.max(active.value - siblings, start.value + boundaries - 1);
1027
1041
  const rightSiblingIndex = Math.min(active.value + siblings, end.value - boundaries);
1028
1042
  const shouldShowLeftDots = leftSiblingIndex > start.value + boundaries + 1;
1029
- const shouldShowRightDots = rightSiblingIndex < end.value - boundaries;
1043
+ const shouldShowRightDots = rightSiblingIndex < end.value - (boundaries + 1);
1030
1044
  if (!shouldShowLeftDots && shouldShowRightDots) {
1031
1045
  const leftItemCount = siblings * 2 + boundaries + 2;
1032
1046
  return [
@@ -1432,8 +1446,8 @@ function useIntersection(options) {
1432
1446
  entry.value = null;
1433
1447
  return;
1434
1448
  }
1435
- observer = new IntersectionObserver(([_entry]) => {
1436
- entry.value = _entry;
1449
+ observer = new IntersectionObserver((entries) => {
1450
+ entry.value = entries[entries.length - 1];
1437
1451
  }, options);
1438
1452
  observer.observe(node);
1439
1453
  }, { immediate: true });
@@ -1536,12 +1550,10 @@ function getHotkeyMatcher(hotkey, usePhysicalKeys) {
1536
1550
  }
1537
1551
  function getHotkeyHandler(hotkeys) {
1538
1552
  return (event) => {
1539
- hotkeys.forEach(([hotkey, handler, options = {
1540
- preventDefault: true,
1541
- usePhysicalKeys: false
1542
- }]) => {
1543
- if (getHotkeyMatcher(hotkey, options.usePhysicalKeys)(event)) {
1544
- if (options.preventDefault) event.preventDefault();
1553
+ hotkeys.forEach(([hotkey, handler, options]) => {
1554
+ const { preventDefault = true, usePhysicalKeys = false } = options || {};
1555
+ if (getHotkeyMatcher(hotkey, usePhysicalKeys)(event)) {
1556
+ if (preventDefault) event.preventDefault();
1545
1557
  handler(event);
1546
1558
  }
1547
1559
  });
@@ -1572,16 +1584,14 @@ function useHotkeys(hotkeys, tagsToIgnore = [
1572
1584
  "select"
1573
1585
  ], triggerOnContentEditable = false) {
1574
1586
  const handleKeydown = (event) => {
1575
- (0, vue.toValue)(hotkeys).forEach(([hotkey, handler, options = {
1576
- preventDefault: true,
1577
- usePhysicalKeys: false
1578
- }]) => {
1579
- if (getHotkeyMatcher(hotkey, options.usePhysicalKeys)(event) && shouldFireEvent(event, (0, vue.toValue)(tagsToIgnore) ?? [
1587
+ (0, vue.toValue)(hotkeys).forEach(([hotkey, handler, options]) => {
1588
+ const { preventDefault = true, usePhysicalKeys = false } = options || {};
1589
+ if (getHotkeyMatcher(hotkey, usePhysicalKeys)(event) && shouldFireEvent(event, (0, vue.toValue)(tagsToIgnore) ?? [
1580
1590
  "input",
1581
1591
  "textarea",
1582
1592
  "select"
1583
1593
  ], (0, vue.toValue)(triggerOnContentEditable))) {
1584
- if (options.preventDefault) event.preventDefault();
1594
+ if (preventDefault) event.preventDefault();
1585
1595
  handler(event);
1586
1596
  }
1587
1597
  });
@@ -2279,7 +2289,13 @@ function useThrottledCallbackWithClearTimeout(callback, wait) {
2279
2289
  let latestOutArgs = null;
2280
2290
  let active = true;
2281
2291
  let timeoutId = -1;
2282
- const clear = () => window.clearTimeout(timeoutId);
2292
+ const clear = () => {
2293
+ window.clearTimeout(timeoutId);
2294
+ timeoutId = -1;
2295
+ active = true;
2296
+ latestInArgs = null;
2297
+ latestOutArgs = null;
2298
+ };
2283
2299
  const callThrottledCallback = (...args) => {
2284
2300
  callback(...args);
2285
2301
  latestInArgs = args;
@@ -3301,7 +3317,7 @@ function findPrevTokenIndex(slots, from) {
3301
3317
  for (let i = from; i >= 0; i--) if (slots[i].type === "token") return i;
3302
3318
  return -1;
3303
3319
  }
3304
- function processInput(inputValue, slots, _slotCharOption) {
3320
+ function processInput(inputValue, slots, _slotCharOption, transform) {
3305
3321
  let result = "";
3306
3322
  let inputIndex = 0;
3307
3323
  for (let slotIndex = 0; slotIndex < slots.length && inputIndex <= inputValue.length; slotIndex++) {
@@ -3313,7 +3329,7 @@ function processInput(inputValue, slots, _slotCharOption) {
3313
3329
  }
3314
3330
  if (inputIndex >= inputValue.length) break;
3315
3331
  while (inputIndex < inputValue.length) {
3316
- const ch = inputValue[inputIndex];
3332
+ const ch = transform ? transform(inputValue[inputIndex]) : inputValue[inputIndex];
3317
3333
  inputIndex++;
3318
3334
  if (slot.pattern.test(ch)) {
3319
3335
  result += ch;
@@ -3435,8 +3451,8 @@ function useMask(options) {
3435
3451
  const initializeInputValue = (inputNode) => {
3436
3452
  if (!inputNode.value) return false;
3437
3453
  const isOwnValue = inputNode.value === display;
3438
- const parse = (slots, slotChar) => isOwnValue ? applyMaskToRaw(rawInternal, slots, slotChar, options.transform) : processInput(inputNode.value, slots, slotChar);
3439
- const { slots: initialSlots, slotChar: initialSlotChar } = getResolvedOptions(options, "");
3454
+ const { slots: initialSlots, slotChar: initialSlotChar, transform } = getResolvedOptions(options, "");
3455
+ const parse = (slots, slotChar) => isOwnValue ? applyMaskToRaw(rawInternal, slots, slotChar, options.transform) : processInput(inputNode.value, slots, slotChar, transform);
3440
3456
  const { slots: resolvedSlots, slotChar } = getResolvedOptions(options, extractRaw(parse(initialSlots, initialSlotChar), initialSlots));
3441
3457
  const reprocessed = parse(resolvedSlots, slotChar);
3442
3458
  const newRaw = extractRaw(reprocessed, resolvedSlots);
@@ -3781,6 +3797,13 @@ function findLastEnabled(total, isItemDisabled) {
3781
3797
  for (let i = total - 1; i >= 0; i -= 1) if (!isItemDisabled(i)) return i;
3782
3798
  return 0;
3783
3799
  }
3800
+ function findEnabledInRow(row, startCol, step, columns, total, isItemDisabled) {
3801
+ for (let col = startCol; col >= 0 && col < columns; col += step) {
3802
+ const candidate = row * columns + col;
3803
+ if (candidate < total && !isItemDisabled(candidate)) return candidate;
3804
+ }
3805
+ return null;
3806
+ }
3784
3807
  var defaultIsItemDisabled = () => false;
3785
3808
  function useRovingIndex(input) {
3786
3809
  const { total, orientation = "horizontal", loop = true, dir = "ltr", activateOnFocus = false, columns, focusedIndex, initialIndex, onFocusChange, isItemDisabled = defaultIsItemDisabled } = input;
@@ -3819,19 +3842,13 @@ function useRovingIndex(input) {
3819
3842
  const isRtl = dir === "rtl";
3820
3843
  switch (event.key) {
3821
3844
  case "ArrowRight": {
3822
- const targetCol = isRtl ? col - 1 : col + 1;
3823
- if (targetCol >= 0 && targetCol < cols && row * cols + targetCol < total_) {
3824
- const candidate = row * cols + targetCol;
3825
- if (!isItemDisabled(candidate)) nextIndex = candidate;
3826
- }
3845
+ const step = isRtl ? -1 : 1;
3846
+ nextIndex = findEnabledInRow(row, col + step, step, cols, total_, isItemDisabled);
3827
3847
  break;
3828
3848
  }
3829
3849
  case "ArrowLeft": {
3830
- const targetCol = isRtl ? col + 1 : col - 1;
3831
- if (targetCol >= 0 && targetCol < cols && row * cols + targetCol < total_) {
3832
- const candidate = row * cols + targetCol;
3833
- if (!isItemDisabled(candidate)) nextIndex = candidate;
3834
- }
3850
+ const step = isRtl ? 1 : -1;
3851
+ nextIndex = findEnabledInRow(row, col + step, step, cols, total_, isItemDisabled);
3835
3852
  break;
3836
3853
  }
3837
3854
  case "ArrowDown":