@mantine/hooks 9.4.3-alpha.0 → 9.5.1-alpha.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.
Files changed (39) hide show
  1. package/cjs/use-collapse/use-collapse.cjs +1 -0
  2. package/cjs/use-collapse/use-horizontal-collapse.cjs +1 -0
  3. package/cjs/use-drag/use-drag.cjs +10 -5
  4. package/cjs/use-drag/use-drag.cjs.map +1 -1
  5. package/cjs/use-favicon/use-favicon.cjs +2 -1
  6. package/cjs/use-favicon/use-favicon.cjs.map +1 -1
  7. package/cjs/use-floating-window/use-floating-window.cjs +9 -12
  8. package/cjs/use-floating-window/use-floating-window.cjs.map +1 -1
  9. package/cjs/use-headroom/use-headroom.cjs +2 -0
  10. package/cjs/use-hotkeys/parse-hotkey.cjs +1 -0
  11. package/cjs/use-hotkeys/use-hotkeys.cjs +1 -0
  12. package/cjs/use-input-state/use-input-state.cjs +1 -0
  13. package/cjs/use-mask/use-mask.cjs +4 -2
  14. package/cjs/use-mask/use-mask.cjs.map +1 -1
  15. package/cjs/use-mouse/use-mouse.cjs +4 -2
  16. package/cjs/use-mouse/use-mouse.cjs.map +1 -1
  17. package/cjs/use-pagination/use-pagination.cjs +9 -5
  18. package/cjs/use-pagination/use-pagination.cjs.map +1 -1
  19. package/cjs/use-set/use-set.cjs +1 -0
  20. package/esm/use-collapse/use-collapse.mjs +1 -1
  21. package/esm/use-collapse/use-horizontal-collapse.mjs +1 -1
  22. package/esm/use-drag/use-drag.mjs +10 -5
  23. package/esm/use-drag/use-drag.mjs.map +1 -1
  24. package/esm/use-favicon/use-favicon.mjs +2 -1
  25. package/esm/use-favicon/use-favicon.mjs.map +1 -1
  26. package/esm/use-floating-window/use-floating-window.mjs +9 -12
  27. package/esm/use-floating-window/use-floating-window.mjs.map +1 -1
  28. package/esm/use-headroom/use-headroom.mjs +1 -1
  29. package/esm/use-hotkeys/parse-hotkey.mjs +1 -1
  30. package/esm/use-hotkeys/use-hotkeys.mjs +2 -2
  31. package/esm/use-input-state/use-input-state.mjs +1 -1
  32. package/esm/use-mask/use-mask.mjs +4 -2
  33. package/esm/use-mask/use-mask.mjs.map +1 -1
  34. package/esm/use-mouse/use-mouse.mjs +4 -2
  35. package/esm/use-mouse/use-mouse.mjs.map +1 -1
  36. package/esm/use-pagination/use-pagination.mjs +9 -6
  37. package/esm/use-pagination/use-pagination.mjs.map +1 -1
  38. package/esm/use-set/use-set.mjs +1 -1
  39. package/package.json +1 -1
@@ -96,6 +96,7 @@ function useCollapse({ transitionDuration, transitionTimingFunction = "ease", on
96
96
  };
97
97
  }
98
98
  //#endregion
99
+ exports.getElementHeight = getElementHeight;
99
100
  exports.useCollapse = useCollapse;
100
101
 
101
102
  //# sourceMappingURL=use-collapse.cjs.map
@@ -96,6 +96,7 @@ function useHorizontalCollapse({ transitionDuration, transitionTimingFunction =
96
96
  };
97
97
  }
98
98
  //#endregion
99
+ exports.getElementWidth = getElementWidth;
99
100
  exports.useHorizontalCollapse = useHorizontalCollapse;
100
101
 
101
102
  //# sourceMappingURL=use-horizontal-collapse.cjs.map
@@ -140,7 +140,8 @@ function useDrag(handler, options = {}) {
140
140
  activateDrag();
141
141
  }
142
142
  const movement = applyAxisConstraint(rawMovement);
143
- const delta = applyAxisConstraint([event.clientX - s.prevXY[0], event.clientY - s.prevXY[1]]);
143
+ const rawDelta = [event.clientX - s.prevXY[0], event.clientY - s.prevXY[1]];
144
+ const delta = applyAxisConstraint(rawDelta);
144
145
  const timeDelta = event.timeStamp - s.prevTimestamp;
145
146
  const velocity = timeDelta > 0 ? [Math.abs(delta[0]) / timeDelta, Math.abs(delta[1]) / timeDelta] : s.lastVelocity;
146
147
  s.lastVelocity = velocity;
@@ -172,7 +173,8 @@ function useDrag(handler, options = {}) {
172
173
  const opts = optionsRef.current;
173
174
  if (!s.thresholdMet) {
174
175
  if (opts.filterTaps) {
175
- const mov = applyAxisConstraint([event.clientX - s.startXY[0], event.clientY - s.startXY[1]]);
176
+ const rawMov = [event.clientX - s.startXY[0], event.clientY - s.startXY[1]];
177
+ const mov = applyAxisConstraint(rawMov);
176
178
  const dist = [Math.abs(mov[0]), Math.abs(mov[1])];
177
179
  const isTap = Math.max(dist[0], dist[1]) < (opts.tapThreshold ?? 3);
178
180
  handlerRef.current({
@@ -196,9 +198,11 @@ function useDrag(handler, options = {}) {
196
198
  resetDrag();
197
199
  return;
198
200
  }
199
- const movement = applyAxisConstraint([event.clientX - s.startXY[0], event.clientY - s.startXY[1]]);
201
+ const rawMovement = [event.clientX - s.startXY[0], event.clientY - s.startXY[1]];
202
+ const movement = applyAxisConstraint(rawMovement);
200
203
  const distance = [Math.abs(movement[0]), Math.abs(movement[1])];
201
- const delta = applyAxisConstraint([event.clientX - s.prevXY[0], event.clientY - s.prevXY[1]]);
204
+ const rawDelta = [event.clientX - s.prevXY[0], event.clientY - s.prevXY[1]];
205
+ const delta = applyAxisConstraint(rawDelta);
202
206
  const velocity = event.timeStamp - s.prevTimestamp > VELOCITY_DECAY_MS ? [0, 0] : s.lastVelocity;
203
207
  const maxDistance = Math.max(distance[0], distance[1]);
204
208
  const tap = opts.filterTaps === true && maxDistance < (opts.tapThreshold ?? 3);
@@ -224,7 +228,8 @@ function useDrag(handler, options = {}) {
224
228
  const onPointerCancel = (event) => {
225
229
  const s = stateRef.current;
226
230
  if (!s.isActive || event.pointerId !== s.pointerId) return;
227
- const movement = applyAxisConstraint([event.clientX - s.startXY[0], event.clientY - s.startXY[1]]);
231
+ const rawMovement = [event.clientX - s.startXY[0], event.clientY - s.startXY[1]];
232
+ const movement = applyAxisConstraint(rawMovement);
228
233
  handlerRef.current({
229
234
  xy: [event.clientX, event.clientY],
230
235
  initial: [...s.startXY],
@@ -1 +1 @@
1
- {"version":3,"file":"use-drag.cjs","names":[],"sources":["../../src/use-drag/use-drag.ts"],"sourcesContent":["// Required to disable for webkit-user-select, although deprecated, it is still required for Safari support\n/* eslint-disable @typescript-eslint/no-deprecated */\nimport { useCallback, useRef, useState } from 'react';\n\ntype Vector2 = [number, number];\n\nexport interface UseDragState {\n /** Current pointer position [x, y] */\n xy: Vector2;\n\n /** Position where the gesture started [x, y] */\n initial: Vector2;\n\n /** Displacement from start [x, y], respects axis constraint */\n movement: Vector2;\n\n /** Change since previous event [x, y] */\n delta: Vector2;\n\n /** Absolute distance per axis [x, y] */\n distance: Vector2;\n\n /** Movement direction per axis: -1, 0, or 1 */\n direction: Vector2;\n\n /** Speed per axis in px/ms */\n velocity: Vector2;\n\n /** Time since drag started in ms */\n elapsedTime: number;\n\n /** `true` on the first handler call after the threshold is met */\n first: boolean;\n\n /** `true` on the last handler call (pointer released or canceled) */\n last: boolean;\n\n /** `true` while the gesture is ongoing */\n active: boolean;\n\n /** `true` when the gesture qualifies as a tap (requires `filterTaps: true`) */\n tap: boolean;\n\n /** `true` when the gesture was interrupted by a `pointercancel` event */\n canceled: boolean;\n\n /** Function to programmatically cancel the current gesture */\n cancel: () => void;\n\n /** The source `PointerEvent` */\n event: PointerEvent;\n}\n\nexport interface UseDragOptions {\n /** Constrain movement to a specific axis. `'lock'` locks to whichever axis has more movement after `axisThreshold` is exceeded. */\n axis?: 'x' | 'y' | 'lock';\n\n /** Movement in px required to determine axis when `axis` is `'lock'`, `1` by default */\n axisThreshold?: number;\n\n /** When `true`, the last state includes `tap: true` when total distance is below `tapThreshold`, `false` by default */\n filterTaps?: boolean;\n\n /** Max displacement in px to still be considered a tap, `3` by default */\n tapThreshold?: number;\n\n /** Minimum displacement in px before the drag activates. Can be a number (both axes) or `[x, y]`. `0` by default */\n threshold?: number | Vector2;\n\n /** Enable or disable the hook, `true` by default */\n enabled?: boolean;\n}\n\nexport interface UseDragReturnValue<T extends HTMLElement = any> {\n /** Ref callback to attach to the draggable element */\n ref: React.RefCallback<T | null>;\n\n /** `true` while the element is being dragged */\n active: boolean;\n}\n\nconst VELOCITY_DECAY_MS = 100;\n\nfunction sign(n: number): -1 | 0 | 1 {\n if (n > 0) {\n return 1;\n }\n if (n < 0) {\n return -1;\n }\n return 0;\n}\n\nfunction getThresholdVector(threshold: number | Vector2 | undefined): Vector2 {\n const t = threshold ?? 0;\n if (typeof t === 'number') {\n return [t, t];\n }\n return t;\n}\n\ninterface DragInternalState {\n isActive: boolean;\n pointerId: number;\n startXY: Vector2;\n prevXY: Vector2;\n startTimestamp: number;\n prevTimestamp: number;\n thresholdMet: boolean;\n firstFired: boolean;\n lockedAxis: 'x' | 'y' | null;\n canceled: boolean;\n lastVelocity: Vector2;\n}\n\nfunction createInitialState(): DragInternalState {\n return {\n isActive: false,\n pointerId: -1,\n startXY: [0, 0],\n prevXY: [0, 0],\n startTimestamp: 0,\n prevTimestamp: 0,\n thresholdMet: false,\n firstFired: false,\n lockedAxis: null,\n canceled: false,\n lastVelocity: [0, 0],\n };\n}\n\nexport function useDrag<T extends HTMLElement = any>(\n handler: (state: UseDragState) => void,\n options: UseDragOptions = {}\n): UseDragReturnValue<T> {\n const [active, setActive] = useState(false);\n\n const handlerRef = useRef(handler);\n handlerRef.current = handler;\n\n const optionsRef = useRef(options);\n optionsRef.current = options;\n\n const stateRef = useRef<DragInternalState>(createInitialState());\n const documentControllerRef = useRef<AbortController | null>(null);\n\n const refCallback: React.RefCallback<T | null> = useCallback((node) => {\n if (!node) {\n return undefined;\n }\n\n const elementController = new AbortController();\n\n const applyAxisConstraint = (v: Vector2): Vector2 => {\n const opts = optionsRef.current;\n const s = stateRef.current;\n\n if (opts.axis === 'x') {\n return [v[0], 0];\n }\n if (opts.axis === 'y') {\n return [0, v[1]];\n }\n if (opts.axis === 'lock') {\n if (s.lockedAxis === null) {\n const t = opts.axisThreshold ?? 1;\n if (Math.abs(v[0]) > t || Math.abs(v[1]) > t) {\n s.lockedAxis = Math.abs(v[0]) >= Math.abs(v[1]) ? 'x' : 'y';\n }\n }\n if (s.lockedAxis === 'x') {\n return [v[0], 0];\n }\n if (s.lockedAxis === 'y') {\n return [0, v[1]];\n }\n }\n return v;\n };\n\n const resetDrag = () => {\n const s = stateRef.current;\n s.isActive = false;\n s.pointerId = -1;\n s.thresholdMet = false;\n s.firstFired = false;\n s.lockedAxis = null;\n s.canceled = false;\n setActive(false);\n document.body.style.userSelect = '';\n document.body.style.webkitUserSelect = '';\n documentControllerRef.current?.abort();\n documentControllerRef.current = null;\n };\n\n const cancel = () => {\n if (stateRef.current.isActive) {\n stateRef.current.canceled = true;\n resetDrag();\n }\n };\n\n const activateDrag = () => {\n setActive(true);\n document.body.style.userSelect = 'none';\n document.body.style.webkitUserSelect = 'none';\n };\n\n const onPointerDown = (event: PointerEvent) => {\n if (optionsRef.current.enabled === false) {\n return;\n }\n if (event.button !== 0) {\n return;\n }\n if (stateRef.current.isActive) {\n return;\n }\n\n const s = stateRef.current;\n s.isActive = true;\n s.pointerId = event.pointerId;\n s.startXY = [event.clientX, event.clientY];\n s.prevXY = [event.clientX, event.clientY];\n s.startTimestamp = event.timeStamp;\n s.prevTimestamp = event.timeStamp;\n s.thresholdMet = false;\n s.firstFired = false;\n s.lockedAxis = null;\n s.canceled = false;\n s.lastVelocity = [0, 0];\n\n const [tx, ty] = getThresholdVector(optionsRef.current.threshold);\n if (tx === 0 && ty === 0) {\n s.thresholdMet = true;\n s.firstFired = true;\n activateDrag();\n\n handlerRef.current({\n xy: [event.clientX, event.clientY],\n initial: [event.clientX, event.clientY],\n movement: [0, 0],\n delta: [0, 0],\n distance: [0, 0],\n direction: [0, 0],\n velocity: [0, 0],\n elapsedTime: 0,\n first: true,\n last: false,\n active: true,\n tap: false,\n canceled: false,\n cancel,\n event,\n });\n }\n\n documentControllerRef.current?.abort();\n documentControllerRef.current = new AbortController();\n const sig = documentControllerRef.current.signal;\n\n document.addEventListener('pointermove', onPointerMove, { signal: sig });\n document.addEventListener('pointerup', onPointerUp, { signal: sig });\n document.addEventListener('pointercancel', onPointerCancel, { signal: sig });\n };\n\n const onPointerMove = (event: PointerEvent) => {\n const s = stateRef.current;\n if (!s.isActive || event.pointerId !== s.pointerId) {\n return;\n }\n\n const rawMovement: Vector2 = [event.clientX - s.startXY[0], event.clientY - s.startXY[1]];\n\n if (!s.thresholdMet) {\n const [tx, ty] = getThresholdVector(optionsRef.current.threshold);\n if (Math.abs(rawMovement[0]) < tx && Math.abs(rawMovement[1]) < ty) {\n s.prevXY = [event.clientX, event.clientY];\n s.prevTimestamp = event.timeStamp;\n return;\n }\n s.thresholdMet = true;\n activateDrag();\n }\n\n const movement = applyAxisConstraint(rawMovement);\n const rawDelta: Vector2 = [event.clientX - s.prevXY[0], event.clientY - s.prevXY[1]];\n const delta = applyAxisConstraint(rawDelta);\n const timeDelta = event.timeStamp - s.prevTimestamp;\n const velocity: Vector2 =\n timeDelta > 0\n ? [Math.abs(delta[0]) / timeDelta, Math.abs(delta[1]) / timeDelta]\n : s.lastVelocity;\n\n s.lastVelocity = velocity;\n const isFirst = !s.firstFired;\n s.firstFired = true;\n s.prevXY = [event.clientX, event.clientY];\n s.prevTimestamp = event.timeStamp;\n\n handlerRef.current({\n xy: [event.clientX, event.clientY],\n initial: [...s.startXY],\n movement,\n delta,\n distance: [Math.abs(movement[0]), Math.abs(movement[1])],\n direction: [sign(delta[0]), sign(delta[1])],\n velocity,\n elapsedTime: event.timeStamp - s.startTimestamp,\n first: isFirst,\n last: false,\n active: true,\n tap: false,\n canceled: false,\n cancel,\n event,\n });\n };\n\n const onPointerUp = (event: PointerEvent) => {\n const s = stateRef.current;\n if (!s.isActive || event.pointerId !== s.pointerId) {\n return;\n }\n\n const opts = optionsRef.current;\n\n if (!s.thresholdMet) {\n if (opts.filterTaps) {\n const rawMov: Vector2 = [event.clientX - s.startXY[0], event.clientY - s.startXY[1]];\n const mov = applyAxisConstraint(rawMov);\n const dist: Vector2 = [Math.abs(mov[0]), Math.abs(mov[1])];\n const maxDist = Math.max(dist[0], dist[1]);\n const isTap = maxDist < (opts.tapThreshold ?? 3);\n\n handlerRef.current({\n xy: [event.clientX, event.clientY],\n initial: [...s.startXY],\n movement: mov,\n delta: mov,\n distance: dist,\n direction: [sign(mov[0]), sign(mov[1])],\n velocity: [0, 0],\n elapsedTime: event.timeStamp - s.startTimestamp,\n first: true,\n last: true,\n active: false,\n tap: isTap,\n canceled: false,\n cancel,\n event,\n });\n }\n resetDrag();\n return;\n }\n\n const rawMovement: Vector2 = [event.clientX - s.startXY[0], event.clientY - s.startXY[1]];\n const movement = applyAxisConstraint(rawMovement);\n const distance: Vector2 = [Math.abs(movement[0]), Math.abs(movement[1])];\n const rawDelta: Vector2 = [event.clientX - s.prevXY[0], event.clientY - s.prevXY[1]];\n const delta = applyAxisConstraint(rawDelta);\n\n const timeSinceLastMove = event.timeStamp - s.prevTimestamp;\n const velocity: Vector2 = timeSinceLastMove > VELOCITY_DECAY_MS ? [0, 0] : s.lastVelocity;\n\n const maxDistance = Math.max(distance[0], distance[1]);\n const tap = opts.filterTaps === true && maxDistance < (opts.tapThreshold ?? 3);\n\n handlerRef.current({\n xy: [event.clientX, event.clientY],\n initial: [...s.startXY],\n movement,\n delta,\n distance,\n direction: [sign(delta[0]), sign(delta[1])],\n velocity,\n elapsedTime: event.timeStamp - s.startTimestamp,\n first: !s.firstFired,\n last: true,\n active: false,\n tap,\n canceled: false,\n cancel,\n event,\n });\n\n resetDrag();\n };\n\n const onPointerCancel = (event: PointerEvent) => {\n const s = stateRef.current;\n if (!s.isActive || event.pointerId !== s.pointerId) {\n return;\n }\n\n const rawMovement: Vector2 = [event.clientX - s.startXY[0], event.clientY - s.startXY[1]];\n const movement = applyAxisConstraint(rawMovement);\n\n handlerRef.current({\n xy: [event.clientX, event.clientY],\n initial: [...s.startXY],\n movement,\n delta: [0, 0],\n distance: [Math.abs(movement[0]), Math.abs(movement[1])],\n direction: [0, 0],\n velocity: [0, 0],\n elapsedTime: event.timeStamp - s.startTimestamp,\n first: !s.firstFired,\n last: true,\n active: false,\n tap: false,\n canceled: true,\n cancel,\n event,\n });\n\n resetDrag();\n };\n\n node.addEventListener('pointerdown', onPointerDown, {\n signal: elementController.signal,\n });\n\n return () => {\n elementController.abort();\n documentControllerRef.current?.abort();\n documentControllerRef.current = null;\n if (stateRef.current.isActive) {\n stateRef.current.isActive = false;\n setActive(false);\n document.body.style.userSelect = '';\n document.body.style.webkitUserSelect = '';\n }\n };\n }, []);\n\n return { ref: refCallback, active };\n}\n\nexport namespace useDrag {\n export type State = UseDragState;\n export type Options = UseDragOptions;\n export type ReturnValue<T extends HTMLElement = any> = UseDragReturnValue<T>;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"use-drag.cjs","names":[],"sources":["../../src/use-drag/use-drag.ts"],"sourcesContent":["// Required to disable for webkit-user-select, although deprecated, it is still required for Safari support\n/* eslint-disable @typescript-eslint/no-deprecated */\nimport { useCallback, useRef, useState } from 'react';\n\ntype Vector2 = [number, number];\n\nexport interface UseDragState {\n /** Current pointer position [x, y] */\n xy: Vector2;\n\n /** Position where the gesture started [x, y] */\n initial: Vector2;\n\n /** Displacement from start [x, y], respects axis constraint */\n movement: Vector2;\n\n /** Change since previous event [x, y] */\n delta: Vector2;\n\n /** Absolute distance per axis [x, y] */\n distance: Vector2;\n\n /** Movement direction per axis: -1, 0, or 1 */\n direction: Vector2;\n\n /** Speed per axis in px/ms */\n velocity: Vector2;\n\n /** Time since drag started in ms */\n elapsedTime: number;\n\n /** `true` on the first handler call after the threshold is met */\n first: boolean;\n\n /** `true` on the last handler call (pointer released or canceled) */\n last: boolean;\n\n /** `true` while the gesture is ongoing */\n active: boolean;\n\n /** `true` when the gesture qualifies as a tap (requires `filterTaps: true`) */\n tap: boolean;\n\n /** `true` when the gesture was interrupted by a `pointercancel` event */\n canceled: boolean;\n\n /** Function to programmatically cancel the current gesture */\n cancel: () => void;\n\n /** The source `PointerEvent` */\n event: PointerEvent;\n}\n\nexport interface UseDragOptions {\n /** Constrain movement to a specific axis. `'lock'` locks to whichever axis has more movement after `axisThreshold` is exceeded. */\n axis?: 'x' | 'y' | 'lock';\n\n /** Movement in px required to determine axis when `axis` is `'lock'`, `1` by default */\n axisThreshold?: number;\n\n /** When `true`, the last state includes `tap: true` when total distance is below `tapThreshold`, `false` by default */\n filterTaps?: boolean;\n\n /** Max displacement in px to still be considered a tap, `3` by default */\n tapThreshold?: number;\n\n /** Minimum displacement in px before the drag activates. Can be a number (both axes) or `[x, y]`. `0` by default */\n threshold?: number | Vector2;\n\n /** Enable or disable the hook, `true` by default */\n enabled?: boolean;\n}\n\nexport interface UseDragReturnValue<T extends HTMLElement = any> {\n /** Ref callback to attach to the draggable element */\n ref: React.RefCallback<T | null>;\n\n /** `true` while the element is being dragged */\n active: boolean;\n}\n\nconst VELOCITY_DECAY_MS = 100;\n\nfunction sign(n: number): -1 | 0 | 1 {\n if (n > 0) {\n return 1;\n }\n if (n < 0) {\n return -1;\n }\n return 0;\n}\n\nfunction getThresholdVector(threshold: number | Vector2 | undefined): Vector2 {\n const t = threshold ?? 0;\n if (typeof t === 'number') {\n return [t, t];\n }\n return t;\n}\n\ninterface DragInternalState {\n isActive: boolean;\n pointerId: number;\n startXY: Vector2;\n prevXY: Vector2;\n startTimestamp: number;\n prevTimestamp: number;\n thresholdMet: boolean;\n firstFired: boolean;\n lockedAxis: 'x' | 'y' | null;\n canceled: boolean;\n lastVelocity: Vector2;\n}\n\nfunction createInitialState(): DragInternalState {\n return {\n isActive: false,\n pointerId: -1,\n startXY: [0, 0],\n prevXY: [0, 0],\n startTimestamp: 0,\n prevTimestamp: 0,\n thresholdMet: false,\n firstFired: false,\n lockedAxis: null,\n canceled: false,\n lastVelocity: [0, 0],\n };\n}\n\nexport function useDrag<T extends HTMLElement = any>(\n handler: (state: UseDragState) => void,\n options: UseDragOptions = {}\n): UseDragReturnValue<T> {\n const [active, setActive] = useState(false);\n\n const handlerRef = useRef(handler);\n handlerRef.current = handler;\n\n const optionsRef = useRef(options);\n optionsRef.current = options;\n\n const stateRef = useRef<DragInternalState>(createInitialState());\n const documentControllerRef = useRef<AbortController | null>(null);\n\n const refCallback: React.RefCallback<T | null> = useCallback((node) => {\n if (!node) {\n return undefined;\n }\n\n const elementController = new AbortController();\n\n const applyAxisConstraint = (v: Vector2): Vector2 => {\n const opts = optionsRef.current;\n const s = stateRef.current;\n\n if (opts.axis === 'x') {\n return [v[0], 0];\n }\n if (opts.axis === 'y') {\n return [0, v[1]];\n }\n if (opts.axis === 'lock') {\n if (s.lockedAxis === null) {\n const t = opts.axisThreshold ?? 1;\n if (Math.abs(v[0]) > t || Math.abs(v[1]) > t) {\n s.lockedAxis = Math.abs(v[0]) >= Math.abs(v[1]) ? 'x' : 'y';\n }\n }\n if (s.lockedAxis === 'x') {\n return [v[0], 0];\n }\n if (s.lockedAxis === 'y') {\n return [0, v[1]];\n }\n }\n return v;\n };\n\n const resetDrag = () => {\n const s = stateRef.current;\n s.isActive = false;\n s.pointerId = -1;\n s.thresholdMet = false;\n s.firstFired = false;\n s.lockedAxis = null;\n s.canceled = false;\n setActive(false);\n document.body.style.userSelect = '';\n document.body.style.webkitUserSelect = '';\n documentControllerRef.current?.abort();\n documentControllerRef.current = null;\n };\n\n const cancel = () => {\n if (stateRef.current.isActive) {\n stateRef.current.canceled = true;\n resetDrag();\n }\n };\n\n const activateDrag = () => {\n setActive(true);\n document.body.style.userSelect = 'none';\n document.body.style.webkitUserSelect = 'none';\n };\n\n const onPointerDown = (event: PointerEvent) => {\n if (optionsRef.current.enabled === false) {\n return;\n }\n if (event.button !== 0) {\n return;\n }\n if (stateRef.current.isActive) {\n return;\n }\n\n const s = stateRef.current;\n s.isActive = true;\n s.pointerId = event.pointerId;\n s.startXY = [event.clientX, event.clientY];\n s.prevXY = [event.clientX, event.clientY];\n s.startTimestamp = event.timeStamp;\n s.prevTimestamp = event.timeStamp;\n s.thresholdMet = false;\n s.firstFired = false;\n s.lockedAxis = null;\n s.canceled = false;\n s.lastVelocity = [0, 0];\n\n const [tx, ty] = getThresholdVector(optionsRef.current.threshold);\n if (tx === 0 && ty === 0) {\n s.thresholdMet = true;\n s.firstFired = true;\n activateDrag();\n\n handlerRef.current({\n xy: [event.clientX, event.clientY],\n initial: [event.clientX, event.clientY],\n movement: [0, 0],\n delta: [0, 0],\n distance: [0, 0],\n direction: [0, 0],\n velocity: [0, 0],\n elapsedTime: 0,\n first: true,\n last: false,\n active: true,\n tap: false,\n canceled: false,\n cancel,\n event,\n });\n }\n\n documentControllerRef.current?.abort();\n documentControllerRef.current = new AbortController();\n const sig = documentControllerRef.current.signal;\n\n document.addEventListener('pointermove', onPointerMove, { signal: sig });\n document.addEventListener('pointerup', onPointerUp, { signal: sig });\n document.addEventListener('pointercancel', onPointerCancel, { signal: sig });\n };\n\n const onPointerMove = (event: PointerEvent) => {\n const s = stateRef.current;\n if (!s.isActive || event.pointerId !== s.pointerId) {\n return;\n }\n\n const rawMovement: Vector2 = [event.clientX - s.startXY[0], event.clientY - s.startXY[1]];\n\n if (!s.thresholdMet) {\n const [tx, ty] = getThresholdVector(optionsRef.current.threshold);\n if (Math.abs(rawMovement[0]) < tx && Math.abs(rawMovement[1]) < ty) {\n s.prevXY = [event.clientX, event.clientY];\n s.prevTimestamp = event.timeStamp;\n return;\n }\n s.thresholdMet = true;\n activateDrag();\n }\n\n const movement = applyAxisConstraint(rawMovement);\n const rawDelta: Vector2 = [event.clientX - s.prevXY[0], event.clientY - s.prevXY[1]];\n const delta = applyAxisConstraint(rawDelta);\n const timeDelta = event.timeStamp - s.prevTimestamp;\n const velocity: Vector2 =\n timeDelta > 0\n ? [Math.abs(delta[0]) / timeDelta, Math.abs(delta[1]) / timeDelta]\n : s.lastVelocity;\n\n s.lastVelocity = velocity;\n const isFirst = !s.firstFired;\n s.firstFired = true;\n s.prevXY = [event.clientX, event.clientY];\n s.prevTimestamp = event.timeStamp;\n\n handlerRef.current({\n xy: [event.clientX, event.clientY],\n initial: [...s.startXY],\n movement,\n delta,\n distance: [Math.abs(movement[0]), Math.abs(movement[1])],\n direction: [sign(delta[0]), sign(delta[1])],\n velocity,\n elapsedTime: event.timeStamp - s.startTimestamp,\n first: isFirst,\n last: false,\n active: true,\n tap: false,\n canceled: false,\n cancel,\n event,\n });\n };\n\n const onPointerUp = (event: PointerEvent) => {\n const s = stateRef.current;\n if (!s.isActive || event.pointerId !== s.pointerId) {\n return;\n }\n\n const opts = optionsRef.current;\n\n if (!s.thresholdMet) {\n if (opts.filterTaps) {\n const rawMov: Vector2 = [event.clientX - s.startXY[0], event.clientY - s.startXY[1]];\n const mov = applyAxisConstraint(rawMov);\n const dist: Vector2 = [Math.abs(mov[0]), Math.abs(mov[1])];\n const maxDist = Math.max(dist[0], dist[1]);\n const isTap = maxDist < (opts.tapThreshold ?? 3);\n\n handlerRef.current({\n xy: [event.clientX, event.clientY],\n initial: [...s.startXY],\n movement: mov,\n delta: mov,\n distance: dist,\n direction: [sign(mov[0]), sign(mov[1])],\n velocity: [0, 0],\n elapsedTime: event.timeStamp - s.startTimestamp,\n first: true,\n last: true,\n active: false,\n tap: isTap,\n canceled: false,\n cancel,\n event,\n });\n }\n resetDrag();\n return;\n }\n\n const rawMovement: Vector2 = [event.clientX - s.startXY[0], event.clientY - s.startXY[1]];\n const movement = applyAxisConstraint(rawMovement);\n const distance: Vector2 = [Math.abs(movement[0]), Math.abs(movement[1])];\n const rawDelta: Vector2 = [event.clientX - s.prevXY[0], event.clientY - s.prevXY[1]];\n const delta = applyAxisConstraint(rawDelta);\n\n const timeSinceLastMove = event.timeStamp - s.prevTimestamp;\n const velocity: Vector2 = timeSinceLastMove > VELOCITY_DECAY_MS ? [0, 0] : s.lastVelocity;\n\n const maxDistance = Math.max(distance[0], distance[1]);\n const tap = opts.filterTaps === true && maxDistance < (opts.tapThreshold ?? 3);\n\n handlerRef.current({\n xy: [event.clientX, event.clientY],\n initial: [...s.startXY],\n movement,\n delta,\n distance,\n direction: [sign(delta[0]), sign(delta[1])],\n velocity,\n elapsedTime: event.timeStamp - s.startTimestamp,\n first: !s.firstFired,\n last: true,\n active: false,\n tap,\n canceled: false,\n cancel,\n event,\n });\n\n resetDrag();\n };\n\n const onPointerCancel = (event: PointerEvent) => {\n const s = stateRef.current;\n if (!s.isActive || event.pointerId !== s.pointerId) {\n return;\n }\n\n const rawMovement: Vector2 = [event.clientX - s.startXY[0], event.clientY - s.startXY[1]];\n const movement = applyAxisConstraint(rawMovement);\n\n handlerRef.current({\n xy: [event.clientX, event.clientY],\n initial: [...s.startXY],\n movement,\n delta: [0, 0],\n distance: [Math.abs(movement[0]), Math.abs(movement[1])],\n direction: [0, 0],\n velocity: [0, 0],\n elapsedTime: event.timeStamp - s.startTimestamp,\n first: !s.firstFired,\n last: true,\n active: false,\n tap: false,\n canceled: true,\n cancel,\n event,\n });\n\n resetDrag();\n };\n\n node.addEventListener('pointerdown', onPointerDown, {\n signal: elementController.signal,\n });\n\n return () => {\n elementController.abort();\n documentControllerRef.current?.abort();\n documentControllerRef.current = null;\n if (stateRef.current.isActive) {\n stateRef.current.isActive = false;\n setActive(false);\n document.body.style.userSelect = '';\n document.body.style.webkitUserSelect = '';\n }\n };\n }, []);\n\n return { ref: refCallback, active };\n}\n\nexport namespace useDrag {\n export type State = UseDragState;\n export type Options = UseDragOptions;\n export type ReturnValue<T extends HTMLElement = any> = UseDragReturnValue<T>;\n}\n"],"mappings":"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"}
@@ -20,7 +20,8 @@ function useFavicon(url) {
20
20
  document.querySelector("head").appendChild(element);
21
21
  }
22
22
  const splittedUrl = url.split(".");
23
- const mimeType = MIME_TYPES[splittedUrl[splittedUrl.length - 1].toLowerCase()];
23
+ const extension = splittedUrl[splittedUrl.length - 1].toLowerCase();
24
+ const mimeType = MIME_TYPES[extension];
24
25
  if (mimeType) link.current.setAttribute("type", mimeType);
25
26
  else link.current.removeAttribute("type");
26
27
  link.current.setAttribute("href", url);
@@ -1 +1 @@
1
- {"version":3,"file":"use-favicon.cjs","names":[],"sources":["../../src/use-favicon/use-favicon.ts"],"sourcesContent":["import { useRef } from 'react';\nimport { useIsomorphicEffect } from '../use-isomorphic-effect/use-isomorphic-effect';\n\nconst MIME_TYPES: Record<string, string> = {\n ico: 'image/x-icon',\n png: 'image/png',\n svg: 'image/svg+xml',\n gif: 'image/gif',\n};\n\nexport function useFavicon(url: string) {\n const link = useRef<HTMLLinkElement>(null);\n\n useIsomorphicEffect(() => {\n if (!url) {\n return;\n }\n\n if (!link.current) {\n const existingElements = document.querySelectorAll<HTMLLinkElement>('link[rel*=\"icon\"]');\n existingElements.forEach((element) => document.head.removeChild(element));\n\n const element = document.createElement('link');\n element.rel = 'shortcut icon';\n link.current = element;\n document.querySelector('head')!.appendChild(element);\n }\n\n const splittedUrl = url.split('.');\n const extension = splittedUrl[splittedUrl.length - 1].toLowerCase();\n const mimeType = MIME_TYPES[extension];\n\n if (mimeType) {\n link.current.setAttribute('type', mimeType);\n } else {\n link.current.removeAttribute('type');\n }\n\n link.current.setAttribute('href', url);\n }, [url]);\n}\n"],"mappings":";;;;AAGA,MAAM,aAAqC;CACzC,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;AACP;AAEA,SAAgB,WAAW,KAAa;CACtC,MAAM,QAAA,GAAA,MAAA,OAAA,CAA+B,IAAI;CAEzC,8BAAA,0BAA0B;EACxB,IAAI,CAAC,KACH;EAGF,IAAI,CAAC,KAAK,SAAS;GAEjB,SADkC,iBAAkC,qBACrD,CAAC,CAAC,SAAS,YAAY,SAAS,KAAK,YAAY,OAAO,CAAC;GAExE,MAAM,UAAU,SAAS,cAAc,MAAM;GAC7C,QAAQ,MAAM;GACd,KAAK,UAAU;GACf,SAAS,cAAc,MAAM,CAAC,CAAE,YAAY,OAAO;EACrD;EAEA,MAAM,cAAc,IAAI,MAAM,GAAG;EAEjC,MAAM,WAAW,WADC,YAAY,YAAY,SAAS,EAAE,CAAC,YAClB;EAEpC,IAAI,UACF,KAAK,QAAQ,aAAa,QAAQ,QAAQ;OAE1C,KAAK,QAAQ,gBAAgB,MAAM;EAGrC,KAAK,QAAQ,aAAa,QAAQ,GAAG;CACvC,GAAG,CAAC,GAAG,CAAC;AACV"}
1
+ {"version":3,"file":"use-favicon.cjs","names":[],"sources":["../../src/use-favicon/use-favicon.ts"],"sourcesContent":["import { useRef } from 'react';\nimport { useIsomorphicEffect } from '../use-isomorphic-effect/use-isomorphic-effect';\n\nconst MIME_TYPES: Record<string, string> = {\n ico: 'image/x-icon',\n png: 'image/png',\n svg: 'image/svg+xml',\n gif: 'image/gif',\n};\n\nexport function useFavicon(url: string) {\n const link = useRef<HTMLLinkElement>(null);\n\n useIsomorphicEffect(() => {\n if (!url) {\n return;\n }\n\n if (!link.current) {\n const existingElements = document.querySelectorAll<HTMLLinkElement>('link[rel*=\"icon\"]');\n existingElements.forEach((element) => document.head.removeChild(element));\n\n const element = document.createElement('link');\n element.rel = 'shortcut icon';\n link.current = element;\n document.querySelector('head')!.appendChild(element);\n }\n\n const splittedUrl = url.split('.');\n const extension = splittedUrl[splittedUrl.length - 1].toLowerCase();\n const mimeType = MIME_TYPES[extension];\n\n if (mimeType) {\n link.current.setAttribute('type', mimeType);\n } else {\n link.current.removeAttribute('type');\n }\n\n link.current.setAttribute('href', url);\n }, [url]);\n}\n"],"mappings":";;;;AAGA,MAAM,aAAqC;CACzC,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;AACP;AAEA,SAAgB,WAAW,KAAa;CACtC,MAAM,QAAA,GAAA,MAAA,OAAA,CAA+B,IAAI;CAEzC,8BAAA,0BAA0B;EACxB,IAAI,CAAC,KACH;EAGF,IAAI,CAAC,KAAK,SAAS;GAEjB,SADkC,iBAAkC,qBACrD,CAAC,CAAC,SAAS,YAAY,SAAS,KAAK,YAAY,OAAO,CAAC;GAExE,MAAM,UAAU,SAAS,cAAc,MAAM;GAC7C,QAAQ,MAAM;GACd,KAAK,UAAU;GACf,SAAS,cAAc,MAAM,CAAC,CAAE,YAAY,OAAO;EACrD;EAEA,MAAM,cAAc,IAAI,MAAM,GAAG;EACjC,MAAM,YAAY,YAAY,YAAY,SAAS,EAAE,CAAC,YAAY;EAClE,MAAM,WAAW,WAAW;EAE5B,IAAI,UACF,KAAK,QAAQ,aAAa,QAAQ,QAAQ;OAE1C,KAAK,QAAQ,gBAAgB,MAAM;EAGrC,KAAK,QAAQ,aAAa,QAAQ,GAAG;CACvC,GAAG,CAAC,GAAG,CAAC;AACV"}
@@ -21,6 +21,9 @@ function useFloatingWindow(options = {}) {
21
21
  const isDraggingRef = (0, react.useRef)(false);
22
22
  const initialized = (0, react.useRef)(false);
23
23
  const enabledRef = useRefValue(options.enabled);
24
+ const onPositionChangeRef = useRefValue(options.onPositionChange);
25
+ const onDragStartRef = useRefValue(options.onDragStart);
26
+ const onDragEndRef = useRefValue(options.onDragEnd);
24
27
  const setDragging = (0, react.useCallback)((value) => {
25
28
  setIsDragging(value);
26
29
  isDraggingRef.current = value;
@@ -74,7 +77,7 @@ function useFloatingWindow(options = {}) {
74
77
  x: point.clientX - rect.left,
75
78
  y: point.clientY - rect.top
76
79
  };
77
- options.onDragStart?.();
80
+ onDragStartRef.current?.();
78
81
  document.addEventListener("mousemove", onMove, { signal });
79
82
  document.addEventListener("mouseup", onEnd, { signal });
80
83
  document.addEventListener("touchmove", onMove, {
@@ -82,6 +85,7 @@ function useFloatingWindow(options = {}) {
82
85
  passive: false
83
86
  });
84
87
  document.addEventListener("touchend", onEnd, { signal });
88
+ document.addEventListener("touchcancel", onEnd, { signal });
85
89
  };
86
90
  const onMove = (e) => {
87
91
  if (!isDraggingRef.current) return;
@@ -111,7 +115,7 @@ function useFloatingWindow(options = {}) {
111
115
  ref.current.style.left = `${x}px`;
112
116
  ref.current.style.top = `${y}px`;
113
117
  }
114
- options.onPositionChange?.({
118
+ onPositionChangeRef.current?.({
115
119
  x,
116
120
  y
117
121
  });
@@ -121,7 +125,7 @@ function useFloatingWindow(options = {}) {
121
125
  setDragging(false);
122
126
  document.body.style.userSelect = "";
123
127
  document.body.style.webkitUserSelect = "";
124
- options.onDragEnd?.();
128
+ onDragEndRef.current?.();
125
129
  }
126
130
  };
127
131
  el.addEventListener("mousedown", onStart, { signal });
@@ -137,9 +141,6 @@ function useFloatingWindow(options = {}) {
137
141
  options.constrainOffset,
138
142
  options.dragHandleSelector,
139
143
  options.axis,
140
- options.onPositionChange,
141
- options.onDragStart,
142
- options.onDragEnd,
143
144
  options.initialPosition?.top,
144
145
  options.initialPosition?.left,
145
146
  options.initialPosition?.right,
@@ -186,15 +187,11 @@ function useFloatingWindow(options = {}) {
186
187
  };
187
188
  el.style.left = `${x}px`;
188
189
  el.style.top = `${y}px`;
189
- options.onPositionChange?.({
190
+ onPositionChangeRef.current?.({
190
191
  x,
191
192
  y
192
193
  });
193
- }, [
194
- options.constrainToViewport,
195
- options.constrainOffset,
196
- options.onPositionChange
197
- ]),
194
+ }, [options.constrainToViewport, options.constrainOffset]),
198
195
  isDragging
199
196
  };
200
197
  }
@@ -1 +1 @@
1
- {"version":3,"file":"use-floating-window.cjs","names":[],"sources":["../../src/use-floating-window/use-floating-window.ts"],"sourcesContent":["// Required to disable for webkit-user-select, although deprecated, it is still required for Safari support\nimport { RefCallback, useCallback, useEffect, useRef, useState } from 'react';\n\nfunction useRefValue<T>(value: T) {\n const ref = useRef(value);\n ref.current = value;\n return ref;\n}\n\ninterface FloatingWindowPositionConfig {\n top?: number;\n left?: number;\n right?: number;\n bottom?: number;\n}\n\ninterface FloatingWindowPosition {\n /** Element offset from the left side of the viewport */\n x: number;\n\n /** Element offset from the top side of the viewport */\n y: number;\n}\n\nexport interface UseFloatingWindowOptions {\n /** If `false`, the element can not be dragged. */\n enabled?: boolean;\n\n /** If `true`, the element can only move within the current viewport boundaries. */\n constrainToViewport?: boolean;\n\n /** The offset from the viewport edges when constraining the element. Requires `constrainToViewport: true`. */\n constrainOffset?: number;\n\n /** Selector of an element that should be used to drag floating window. If not specified, the entire root element is used as a drag target. */\n dragHandleSelector?: string;\n\n /** Selector of an element within `dragHandleSelector` that should be excluded from the drag event. */\n excludeDragHandleSelector?: string;\n\n /** If set, restricts movement to the specified axis */\n axis?: 'x' | 'y';\n\n /** Initial position. If not set, calculated from element styles. */\n initialPosition?: FloatingWindowPositionConfig;\n\n /** Called when the element position changes */\n onPositionChange?: (pos: FloatingWindowPosition) => void;\n\n /** Called when the drag starts */\n onDragStart?: () => void;\n\n /** Called when the drag stops */\n onDragEnd?: () => void;\n}\n\nexport type SetFloatingWindowPosition = (position: FloatingWindowPositionConfig) => void;\n\nexport interface UseFloatingWindowReturnValue<T extends HTMLElement> {\n /** Ref to the element that should be draggable */\n ref: RefCallback<T | null>;\n\n /** Function to set the position of the element */\n setPosition: SetFloatingWindowPosition;\n\n /** `true` if the element is currently being dragged */\n isDragging: boolean;\n}\n\nexport function useFloatingWindow<T extends HTMLElement>(\n options: UseFloatingWindowOptions = {}\n): UseFloatingWindowReturnValue<T> {\n const [element, setElement] = useState<T | null>(null);\n const ref = useRef<T>(null);\n const pos = useRef({ x: 0, y: 0 });\n const offset = useRef({ x: 0, y: 0 });\n const [isDragging, setIsDragging] = useState(false);\n const isDraggingRef = useRef(false);\n const initialized = useRef(false);\n const enabledRef = useRefValue(options.enabled);\n\n const setDragging = useCallback((value: boolean) => {\n setIsDragging(value);\n isDraggingRef.current = value;\n }, []);\n\n const assignRef = useCallback((node: T | null) => {\n if (node) {\n ref.current = node;\n setElement(node);\n } else {\n ref.current = null;\n setElement(null);\n }\n }, []);\n\n useEffect(() => {\n const el = ref.current;\n if (!initialized.current && el) {\n initialized.current = true;\n pos.current = calculateInitialPosition(el, options);\n el.style.left = `${pos.current.x}px`;\n el.style.top = `${pos.current.y}px`;\n el.style.right = 'unset';\n el.style.bottom = 'unset';\n }\n\n return () => {\n initialized.current = false;\n };\n }, [\n element,\n options.constrainOffset,\n options.initialPosition?.top,\n options.initialPosition?.left,\n options.initialPosition?.right,\n options.initialPosition?.bottom,\n options.constrainToViewport,\n ]);\n\n useEffect(() => {\n const el = ref.current;\n if (!el) {\n return;\n }\n\n const controller = new AbortController();\n const signal = controller.signal;\n\n const onStart = (e: MouseEvent | TouchEvent) => {\n if (enabledRef.current === false) {\n return;\n }\n\n const point = 'touches' in e ? e.touches[0] : e;\n\n if ('button' in e && e.button !== 0) {\n return;\n }\n\n if (!getHandle(el, e.target, options)) {\n return;\n }\n\n setDragging(true);\n document.body.style.userSelect = 'none';\n document.body.style.webkitUserSelect = 'none';\n\n const rect = el.getBoundingClientRect();\n\n offset.current = {\n x: point.clientX - rect.left,\n y: point.clientY - rect.top,\n };\n\n options.onDragStart?.();\n\n document.addEventListener('mousemove', onMove, { signal });\n document.addEventListener('mouseup', onEnd, { signal });\n document.addEventListener('touchmove', onMove, { signal, passive: false });\n document.addEventListener('touchend', onEnd, { signal });\n };\n\n const onMove = (e: MouseEvent | TouchEvent) => {\n if (!isDraggingRef.current) {\n return;\n }\n\n const point = 'touches' in e ? e.touches[0] : e;\n e.preventDefault();\n\n let x = point.clientX - offset.current.x;\n let y = point.clientY - offset.current.y;\n\n const constrained = getConstrainedPosition(el, { x, y }, options);\n if (options.axis === 'x') {\n x = constrained.x;\n y = pos.current.y;\n } else if (options.axis === 'y') {\n x = pos.current.x;\n y = constrained.y;\n } else {\n x = constrained.x;\n y = constrained.y;\n }\n\n pos.current = { x, y };\n\n if (ref.current) {\n ref.current.style.left = `${x}px`;\n ref.current.style.top = `${y}px`;\n }\n\n options.onPositionChange?.({ x, y });\n };\n\n const onEnd = () => {\n if (isDraggingRef.current) {\n setDragging(false);\n document.body.style.userSelect = '';\n document.body.style.webkitUserSelect = '';\n options.onDragEnd?.();\n }\n };\n\n el.addEventListener('mousedown', onStart, { signal });\n el.addEventListener('touchstart', onStart, { signal, passive: false });\n\n return () => {\n controller.abort();\n };\n }, [\n options.constrainToViewport,\n options.constrainOffset,\n options.dragHandleSelector,\n options.axis,\n options.onPositionChange,\n options.onDragStart,\n options.onDragEnd,\n options.initialPosition?.top,\n options.initialPosition?.left,\n options.initialPosition?.right,\n options.initialPosition?.bottom,\n element,\n ]);\n\n useEffect(() => {\n const el = ref.current;\n if (!el) {\n return;\n }\n\n const observer = new ResizeObserver(() => {\n // Re-clamp current position if element size changes\n const constrained = getConstrainedPosition(el, pos.current, options);\n pos.current = constrained;\n el.style.left = `${constrained.x}px`;\n el.style.top = `${constrained.y}px`;\n });\n\n observer.observe(el);\n\n return () => {\n observer.disconnect();\n };\n }, [options.constrainToViewport, options.constrainOffset]);\n\n const setPosition = useCallback(\n (position: FloatingWindowPositionConfig) => {\n const el = ref.current;\n if (!el) {\n return;\n }\n\n const offset = options.constrainOffset ?? 0;\n const rect = el.getBoundingClientRect();\n\n let x: number | undefined;\n let y: number | undefined;\n\n if (position.left != null) {\n x = position.left;\n } else if (position.right != null) {\n x = window.innerWidth - rect.width - position.right;\n }\n\n if (position.top != null) {\n y = position.top;\n } else if (position.bottom != null) {\n y = window.innerHeight - rect.height - position.bottom;\n }\n\n x = x ?? pos.current.x;\n y = y ?? pos.current.y;\n\n if (options.constrainToViewport) {\n const clamped = clampToViewport(x, y, el, offset);\n x = clamped.x;\n y = clamped.y;\n }\n\n pos.current = { x, y };\n el.style.left = `${x}px`;\n el.style.top = `${y}px`;\n options.onPositionChange?.({ x, y });\n },\n [options.constrainToViewport, options.constrainOffset, options.onPositionChange]\n );\n\n return {\n ref: assignRef,\n setPosition,\n isDragging,\n };\n}\n\n// -------------------------------------------------------\n// Helper functions\n// -------------------------------------------------------\n\nfunction px(v: string) {\n return v.endsWith('px') ? parseFloat(v) : 0;\n}\n\nfunction calculateInitialPosition(\n el: HTMLElement,\n options: UseFloatingWindowOptions\n): { x: number; y: number } {\n const rect = el.getBoundingClientRect();\n const offset = options.constrainOffset ?? 0;\n const winW = window.innerWidth;\n const winH = window.innerHeight;\n const style = window.getComputedStyle(el);\n const top = options.initialPosition?.top;\n const left = options.initialPosition?.left;\n const right = options.initialPosition?.right;\n const bottom = options.initialPosition?.bottom;\n\n let x = offset;\n let y = offset;\n\n if (left != null) {\n x = left;\n } else if (right != null) {\n x = winW - rect.width - right;\n } else {\n x = px(style.left) || winW - rect.width - px(style.right) || offset;\n }\n\n if (top != null) {\n y = top;\n } else if (bottom != null) {\n y = winH - rect.height - bottom;\n } else {\n y = px(style.top) || winH - rect.height - px(style.bottom) || offset;\n }\n\n return options.constrainToViewport\n ? clampToViewport(x, y, el, options.constrainOffset)\n : { x, y };\n}\n\nfunction getConstrainedPosition(\n el: HTMLElement,\n pos: FloatingWindowPosition,\n options: UseFloatingWindowOptions\n) {\n if (!options.constrainToViewport || !el) {\n return pos;\n }\n\n const rect = el.getBoundingClientRect();\n const offset = options.constrainOffset ?? 0;\n const maxX = window.innerWidth - rect.width - offset;\n const maxY = window.innerHeight - rect.height - offset;\n\n return {\n x: Math.min(Math.max(offset, pos.x), maxX),\n y: Math.min(Math.max(offset, pos.y), maxY),\n };\n}\n\nfunction matchesExcludeSelector(target: Node, excludeSelector?: string): boolean {\n if (!excludeSelector) {\n return false;\n }\n if (!(target instanceof Element)) {\n return false;\n }\n\n return Boolean(target.closest(excludeSelector));\n}\n\nfunction getHandle(\n el: HTMLElement,\n target: EventTarget | null,\n options: UseFloatingWindowOptions\n): boolean {\n if (!(target instanceof Node)) {\n return false;\n }\n\n // If no drag handle selector, allow dragging from entire element\n if (!options.dragHandleSelector) {\n return !matchesExcludeSelector(target, options.excludeDragHandleSelector);\n }\n\n const handles = Array.from(el.querySelectorAll(options.dragHandleSelector));\n return handles.some(\n (handle) =>\n handle.contains(target) && !matchesExcludeSelector(target, options.excludeDragHandleSelector)\n );\n}\n\nfunction clampToViewport(\n x: number,\n y: number,\n el: HTMLElement,\n offset: number = 0\n): { x: number; y: number } {\n const rect = el.getBoundingClientRect();\n const maxX = window.innerWidth - rect.width - offset;\n const maxY = window.innerHeight - rect.height - offset;\n\n return {\n x: Math.min(Math.max(offset, x), maxX),\n y: Math.min(Math.max(offset, y), maxY),\n };\n}\n\nexport namespace useFloatingWindow {\n export type Options = UseFloatingWindowOptions;\n export type Position = FloatingWindowPosition;\n export type SetPosition = SetFloatingWindowPosition;\n export type ReturnValue<T extends HTMLElement> = UseFloatingWindowReturnValue<T>;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"use-floating-window.cjs","names":[],"sources":["../../src/use-floating-window/use-floating-window.ts"],"sourcesContent":["// Required to disable for webkit-user-select, although deprecated, it is still required for Safari support\nimport { RefCallback, useCallback, useEffect, useRef, useState } from 'react';\n\nfunction useRefValue<T>(value: T) {\n const ref = useRef(value);\n ref.current = value;\n return ref;\n}\n\ninterface FloatingWindowPositionConfig {\n top?: number;\n left?: number;\n right?: number;\n bottom?: number;\n}\n\ninterface FloatingWindowPosition {\n /** Element offset from the left side of the viewport */\n x: number;\n\n /** Element offset from the top side of the viewport */\n y: number;\n}\n\nexport interface UseFloatingWindowOptions {\n /** If `false`, the element can not be dragged. */\n enabled?: boolean;\n\n /** If `true`, the element can only move within the current viewport boundaries. */\n constrainToViewport?: boolean;\n\n /** The offset from the viewport edges when constraining the element. Requires `constrainToViewport: true`. */\n constrainOffset?: number;\n\n /** Selector of an element that should be used to drag floating window. If not specified, the entire root element is used as a drag target. */\n dragHandleSelector?: string;\n\n /** Selector of an element within `dragHandleSelector` that should be excluded from the drag event. */\n excludeDragHandleSelector?: string;\n\n /** If set, restricts movement to the specified axis */\n axis?: 'x' | 'y';\n\n /** Initial position. If not set, calculated from element styles. */\n initialPosition?: FloatingWindowPositionConfig;\n\n /** Called when the element position changes */\n onPositionChange?: (pos: FloatingWindowPosition) => void;\n\n /** Called when the drag starts */\n onDragStart?: () => void;\n\n /** Called when the drag stops */\n onDragEnd?: () => void;\n}\n\nexport type SetFloatingWindowPosition = (position: FloatingWindowPositionConfig) => void;\n\nexport interface UseFloatingWindowReturnValue<T extends HTMLElement> {\n /** Ref to the element that should be draggable */\n ref: RefCallback<T | null>;\n\n /** Function to set the position of the element */\n setPosition: SetFloatingWindowPosition;\n\n /** `true` if the element is currently being dragged */\n isDragging: boolean;\n}\n\nexport function useFloatingWindow<T extends HTMLElement>(\n options: UseFloatingWindowOptions = {}\n): UseFloatingWindowReturnValue<T> {\n const [element, setElement] = useState<T | null>(null);\n const ref = useRef<T>(null);\n const pos = useRef({ x: 0, y: 0 });\n const offset = useRef({ x: 0, y: 0 });\n const [isDragging, setIsDragging] = useState(false);\n const isDraggingRef = useRef(false);\n const initialized = useRef(false);\n const enabledRef = useRefValue(options.enabled);\n const onPositionChangeRef = useRefValue(options.onPositionChange);\n const onDragStartRef = useRefValue(options.onDragStart);\n const onDragEndRef = useRefValue(options.onDragEnd);\n\n const setDragging = useCallback((value: boolean) => {\n setIsDragging(value);\n isDraggingRef.current = value;\n }, []);\n\n const assignRef = useCallback((node: T | null) => {\n if (node) {\n ref.current = node;\n setElement(node);\n } else {\n ref.current = null;\n setElement(null);\n }\n }, []);\n\n useEffect(() => {\n const el = ref.current;\n if (!initialized.current && el) {\n initialized.current = true;\n pos.current = calculateInitialPosition(el, options);\n el.style.left = `${pos.current.x}px`;\n el.style.top = `${pos.current.y}px`;\n el.style.right = 'unset';\n el.style.bottom = 'unset';\n }\n\n return () => {\n initialized.current = false;\n };\n }, [\n element,\n options.constrainOffset,\n options.initialPosition?.top,\n options.initialPosition?.left,\n options.initialPosition?.right,\n options.initialPosition?.bottom,\n options.constrainToViewport,\n ]);\n\n useEffect(() => {\n const el = ref.current;\n if (!el) {\n return;\n }\n\n const controller = new AbortController();\n const signal = controller.signal;\n\n const onStart = (e: MouseEvent | TouchEvent) => {\n if (enabledRef.current === false) {\n return;\n }\n\n const point = 'touches' in e ? e.touches[0] : e;\n\n if ('button' in e && e.button !== 0) {\n return;\n }\n\n if (!getHandle(el, e.target, options)) {\n return;\n }\n\n setDragging(true);\n document.body.style.userSelect = 'none';\n document.body.style.webkitUserSelect = 'none';\n\n const rect = el.getBoundingClientRect();\n\n offset.current = {\n x: point.clientX - rect.left,\n y: point.clientY - rect.top,\n };\n\n onDragStartRef.current?.();\n\n document.addEventListener('mousemove', onMove, { signal });\n document.addEventListener('mouseup', onEnd, { signal });\n document.addEventListener('touchmove', onMove, { signal, passive: false });\n document.addEventListener('touchend', onEnd, { signal });\n document.addEventListener('touchcancel', onEnd, { signal });\n };\n\n const onMove = (e: MouseEvent | TouchEvent) => {\n if (!isDraggingRef.current) {\n return;\n }\n\n const point = 'touches' in e ? e.touches[0] : e;\n e.preventDefault();\n\n let x = point.clientX - offset.current.x;\n let y = point.clientY - offset.current.y;\n\n const constrained = getConstrainedPosition(el, { x, y }, options);\n if (options.axis === 'x') {\n x = constrained.x;\n y = pos.current.y;\n } else if (options.axis === 'y') {\n x = pos.current.x;\n y = constrained.y;\n } else {\n x = constrained.x;\n y = constrained.y;\n }\n\n pos.current = { x, y };\n\n if (ref.current) {\n ref.current.style.left = `${x}px`;\n ref.current.style.top = `${y}px`;\n }\n\n onPositionChangeRef.current?.({ x, y });\n };\n\n const onEnd = () => {\n if (isDraggingRef.current) {\n setDragging(false);\n document.body.style.userSelect = '';\n document.body.style.webkitUserSelect = '';\n onDragEndRef.current?.();\n }\n };\n\n el.addEventListener('mousedown', onStart, { signal });\n el.addEventListener('touchstart', onStart, { signal, passive: false });\n\n return () => {\n controller.abort();\n };\n }, [\n options.constrainToViewport,\n options.constrainOffset,\n options.dragHandleSelector,\n options.axis,\n options.initialPosition?.top,\n options.initialPosition?.left,\n options.initialPosition?.right,\n options.initialPosition?.bottom,\n element,\n ]);\n\n useEffect(() => {\n const el = ref.current;\n if (!el) {\n return;\n }\n\n const observer = new ResizeObserver(() => {\n // Re-clamp current position if element size changes\n const constrained = getConstrainedPosition(el, pos.current, options);\n pos.current = constrained;\n el.style.left = `${constrained.x}px`;\n el.style.top = `${constrained.y}px`;\n });\n\n observer.observe(el);\n\n return () => {\n observer.disconnect();\n };\n }, [options.constrainToViewport, options.constrainOffset]);\n\n const setPosition = useCallback(\n (position: FloatingWindowPositionConfig) => {\n const el = ref.current;\n if (!el) {\n return;\n }\n\n const offset = options.constrainOffset ?? 0;\n const rect = el.getBoundingClientRect();\n\n let x: number | undefined;\n let y: number | undefined;\n\n if (position.left != null) {\n x = position.left;\n } else if (position.right != null) {\n x = window.innerWidth - rect.width - position.right;\n }\n\n if (position.top != null) {\n y = position.top;\n } else if (position.bottom != null) {\n y = window.innerHeight - rect.height - position.bottom;\n }\n\n x = x ?? pos.current.x;\n y = y ?? pos.current.y;\n\n if (options.constrainToViewport) {\n const clamped = clampToViewport(x, y, el, offset);\n x = clamped.x;\n y = clamped.y;\n }\n\n pos.current = { x, y };\n el.style.left = `${x}px`;\n el.style.top = `${y}px`;\n onPositionChangeRef.current?.({ x, y });\n },\n [options.constrainToViewport, options.constrainOffset]\n );\n\n return {\n ref: assignRef,\n setPosition,\n isDragging,\n };\n}\n\n// -------------------------------------------------------\n// Helper functions\n// -------------------------------------------------------\n\nfunction px(v: string) {\n return v.endsWith('px') ? parseFloat(v) : 0;\n}\n\nfunction calculateInitialPosition(\n el: HTMLElement,\n options: UseFloatingWindowOptions\n): { x: number; y: number } {\n const rect = el.getBoundingClientRect();\n const offset = options.constrainOffset ?? 0;\n const winW = window.innerWidth;\n const winH = window.innerHeight;\n const style = window.getComputedStyle(el);\n const top = options.initialPosition?.top;\n const left = options.initialPosition?.left;\n const right = options.initialPosition?.right;\n const bottom = options.initialPosition?.bottom;\n\n let x = offset;\n let y = offset;\n\n if (left != null) {\n x = left;\n } else if (right != null) {\n x = winW - rect.width - right;\n } else {\n x = px(style.left) || winW - rect.width - px(style.right) || offset;\n }\n\n if (top != null) {\n y = top;\n } else if (bottom != null) {\n y = winH - rect.height - bottom;\n } else {\n y = px(style.top) || winH - rect.height - px(style.bottom) || offset;\n }\n\n return options.constrainToViewport\n ? clampToViewport(x, y, el, options.constrainOffset)\n : { x, y };\n}\n\nfunction getConstrainedPosition(\n el: HTMLElement,\n pos: FloatingWindowPosition,\n options: UseFloatingWindowOptions\n) {\n if (!options.constrainToViewport || !el) {\n return pos;\n }\n\n const rect = el.getBoundingClientRect();\n const offset = options.constrainOffset ?? 0;\n const maxX = window.innerWidth - rect.width - offset;\n const maxY = window.innerHeight - rect.height - offset;\n\n return {\n x: Math.min(Math.max(offset, pos.x), maxX),\n y: Math.min(Math.max(offset, pos.y), maxY),\n };\n}\n\nfunction matchesExcludeSelector(target: Node, excludeSelector?: string): boolean {\n if (!excludeSelector) {\n return false;\n }\n if (!(target instanceof Element)) {\n return false;\n }\n\n return Boolean(target.closest(excludeSelector));\n}\n\nfunction getHandle(\n el: HTMLElement,\n target: EventTarget | null,\n options: UseFloatingWindowOptions\n): boolean {\n if (!(target instanceof Node)) {\n return false;\n }\n\n // If no drag handle selector, allow dragging from entire element\n if (!options.dragHandleSelector) {\n return !matchesExcludeSelector(target, options.excludeDragHandleSelector);\n }\n\n const handles = Array.from(el.querySelectorAll(options.dragHandleSelector));\n return handles.some(\n (handle) =>\n handle.contains(target) && !matchesExcludeSelector(target, options.excludeDragHandleSelector)\n );\n}\n\nfunction clampToViewport(\n x: number,\n y: number,\n el: HTMLElement,\n offset: number = 0\n): { x: number; y: number } {\n const rect = el.getBoundingClientRect();\n const maxX = window.innerWidth - rect.width - offset;\n const maxY = window.innerHeight - rect.height - offset;\n\n return {\n x: Math.min(Math.max(offset, x), maxX),\n y: Math.min(Math.max(offset, y), maxY),\n };\n}\n\nexport namespace useFloatingWindow {\n export type Options = UseFloatingWindowOptions;\n export type Position = FloatingWindowPosition;\n export type SetPosition = SetFloatingWindowPosition;\n export type ReturnValue<T extends HTMLElement> = UseFloatingWindowReturnValue<T>;\n}\n"],"mappings":"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"}
@@ -74,6 +74,8 @@ function useHeadroom({ fixedAt = 0, scrollDistance = 100, onPin, onFix, onReleas
74
74
  };
75
75
  }
76
76
  //#endregion
77
+ exports.isFixed = isFixed;
78
+ exports.isPinnedOrReleased = isPinnedOrReleased;
77
79
  exports.useHeadroom = useHeadroom;
78
80
 
79
81
  //# sourceMappingURL=use-headroom.cjs.map
@@ -83,5 +83,6 @@ function getHotkeyHandler(hotkeys) {
83
83
  //#endregion
84
84
  exports.getHotkeyHandler = getHotkeyHandler;
85
85
  exports.getHotkeyMatcher = getHotkeyMatcher;
86
+ exports.parseHotkey = parseHotkey;
86
87
 
87
88
  //# sourceMappingURL=parse-hotkey.cjs.map
@@ -31,6 +31,7 @@ function useHotkeys(hotkeys, tagsToIgnore = [
31
31
  }, []);
32
32
  }
33
33
  //#endregion
34
+ exports.getHotkeyHandler = require_parse_hotkey.getHotkeyHandler;
34
35
  exports.useHotkeys = useHotkeys;
35
36
 
36
37
  //# sourceMappingURL=use-hotkeys.cjs.map
@@ -17,6 +17,7 @@ function useInputState(initialState) {
17
17
  return [value, getInputOnChange(setValue)];
18
18
  }
19
19
  //#endregion
20
+ exports.getInputOnChange = getInputOnChange;
20
21
  exports.useInputState = useInputState;
21
22
 
22
23
  //# sourceMappingURL=use-input-state.cjs.map
@@ -250,10 +250,11 @@ function useMask(options) {
250
250
  const newRaw = extractRaw(reprocessed, resolvedSlots);
251
251
  const showSlots = opts.alwaysShowMask || isFocusedRef.current;
252
252
  const showOnFocus = opts.showMaskOnFocus !== false;
253
+ const displayValue = buildDisplayValue(reprocessed, resolvedSlots, slotChar, showSlots && (showOnFocus || reprocessed.length > 0));
253
254
  applyValue({
254
255
  reprocessed,
255
256
  newRaw,
256
- displayValue: buildDisplayValue(reprocessed, resolvedSlots, slotChar, showSlots && (showOnFocus || reprocessed.length > 0)),
257
+ displayValue,
257
258
  resolvedSlots,
258
259
  notifyChange: false
259
260
  });
@@ -275,7 +276,8 @@ function useMask(options) {
275
276
  const applyHistoryState = (0, react.useCallback)((target) => {
276
277
  const opts = optionsRef.current;
277
278
  const { slots, slotChar, transform } = getResolvedOptions(opts, target.rawValue);
278
- updateValue(applyMaskToRaw(target.rawValue, slots, slotChar, transform), target.selectionStart);
279
+ const newMasked = applyMaskToRaw(target.rawValue, slots, slotChar, transform);
280
+ updateValue(newMasked, target.selectionStart);
279
281
  }, [updateValue]);
280
282
  const handleInput = (0, react.useCallback)((e) => {
281
283
  const input = e.target;