@mantine/hooks 9.5.2 → 9.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.
Files changed (93) hide show
  1. package/cjs/use-click-outside/use-click-outside.cjs.map +1 -1
  2. package/cjs/use-clipboard/use-clipboard.cjs.map +1 -1
  3. package/cjs/use-collapse/use-collapse.cjs.map +1 -1
  4. package/cjs/use-collapse/use-horizontal-collapse.cjs.map +1 -1
  5. package/cjs/use-counter/use-counter.cjs.map +1 -1
  6. package/cjs/use-debounced-callback/use-debounced-callback.cjs.map +1 -1
  7. package/cjs/use-debounced-state/use-debounced-state.cjs.map +1 -1
  8. package/cjs/use-debounced-value/use-debounced-value.cjs.map +1 -1
  9. package/cjs/use-did-update/use-did-update.cjs.map +1 -1
  10. package/cjs/use-disclosure/use-disclosure.cjs.map +1 -1
  11. package/cjs/use-document-visibility/use-document-visibility.cjs.map +1 -1
  12. package/cjs/use-drag/use-drag.cjs.map +1 -1
  13. package/cjs/use-event-listener/use-event-listener.cjs.map +1 -1
  14. package/cjs/use-eye-dropper/use-eye-dropper.cjs.map +1 -1
  15. package/cjs/use-favicon/use-favicon.cjs.map +1 -1
  16. package/cjs/use-fetch/use-fetch.cjs.map +1 -1
  17. package/cjs/use-file-dialog/use-file-dialog.cjs.map +1 -1
  18. package/cjs/use-floating-window/use-floating-window.cjs.map +1 -1
  19. package/cjs/use-focus-return/use-focus-return.cjs.map +1 -1
  20. package/cjs/use-focus-trap/use-focus-trap.cjs.map +1 -1
  21. package/cjs/use-focus-within/use-focus-within.cjs.map +1 -1
  22. package/cjs/use-force-update/use-force-update.cjs.map +1 -1
  23. package/cjs/use-fullscreen/use-fullscreen.cjs.map +1 -1
  24. package/cjs/use-hash/use-hash.cjs.map +1 -1
  25. package/cjs/use-headroom/use-headroom.cjs.map +1 -1
  26. package/cjs/use-hotkeys/parse-hotkey.cjs.map +1 -1
  27. package/cjs/use-hotkeys/use-hotkeys.cjs.map +1 -1
  28. package/cjs/use-hover/use-hover.cjs.map +1 -1
  29. package/cjs/use-id/use-id.cjs +2 -1
  30. package/cjs/use-id/use-id.cjs.map +1 -1
  31. package/cjs/use-idle/use-idle.cjs.map +1 -1
  32. package/cjs/use-in-viewport/use-in-viewport.cjs.map +1 -1
  33. package/cjs/use-input-state/use-input-state.cjs.map +1 -1
  34. package/cjs/use-intersection/use-intersection.cjs.map +1 -1
  35. package/cjs/use-interval/use-interval.cjs.map +1 -1
  36. package/cjs/use-is-first-render/use-is-first-render.cjs.map +1 -1
  37. package/cjs/use-list-state/use-list-state.cjs.map +1 -1
  38. package/cjs/use-local-storage/create-storage.cjs.map +1 -1
  39. package/cjs/use-long-press/use-long-press.cjs +2 -1
  40. package/cjs/use-long-press/use-long-press.cjs.map +1 -1
  41. package/cjs/use-map/use-map.cjs.map +1 -1
  42. package/cjs/use-mask/use-mask.cjs +9 -7
  43. package/cjs/use-mask/use-mask.cjs.map +1 -1
  44. package/cjs/use-media-query/use-media-query.cjs.map +1 -1
  45. package/cjs/use-merged-ref/use-merged-ref.cjs.map +1 -1
  46. package/cjs/use-mounted/use-mounted.cjs.map +1 -1
  47. package/cjs/use-mouse/use-mouse.cjs.map +1 -1
  48. package/cjs/use-move/use-move.cjs.map +1 -1
  49. package/cjs/use-mutation-observer/use-mutation-observer.cjs.map +1 -1
  50. package/cjs/use-network/use-network.cjs.map +1 -1
  51. package/cjs/use-orientation/use-orientation.cjs.map +1 -1
  52. package/cjs/use-os/use-os.cjs.map +1 -1
  53. package/cjs/use-page-leave/use-page-leave.cjs.map +1 -1
  54. package/cjs/use-pagination/use-pagination.cjs.map +1 -1
  55. package/cjs/use-previous/use-previous.cjs.map +1 -1
  56. package/cjs/use-queue/use-queue.cjs.map +1 -1
  57. package/cjs/use-radial-move/use-radial-move.cjs.map +1 -1
  58. package/cjs/use-resize-observer/use-resize-observer.cjs.map +1 -1
  59. package/cjs/use-roving-index/use-roving-index.cjs +11 -14
  60. package/cjs/use-roving-index/use-roving-index.cjs.map +1 -1
  61. package/cjs/use-scroll-direction/use-scroll-direction.cjs.map +1 -1
  62. package/cjs/use-scroll-into-view/use-scroll-into-view.cjs.map +1 -1
  63. package/cjs/use-scroll-spy/use-scroll-spy.cjs.map +1 -1
  64. package/cjs/use-scroller/use-scroller.cjs.map +1 -1
  65. package/cjs/use-selection/use-selection.cjs.map +1 -1
  66. package/cjs/use-set/use-set.cjs.map +1 -1
  67. package/cjs/use-set-state/use-set-state.cjs.map +1 -1
  68. package/cjs/use-shallow-effect/use-shallow-effect.cjs.map +1 -1
  69. package/cjs/use-splitter/use-splitter.cjs.map +1 -1
  70. package/cjs/use-state-history/use-state-history.cjs.map +1 -1
  71. package/cjs/use-text-selection/use-text-selection.cjs.map +1 -1
  72. package/cjs/use-throttled-callback/use-throttled-callback.cjs.map +1 -1
  73. package/cjs/use-throttled-state/use-throttled-state.cjs.map +1 -1
  74. package/cjs/use-throttled-value/use-throttled-value.cjs.map +1 -1
  75. package/cjs/use-timeout/use-timeout.cjs.map +1 -1
  76. package/cjs/use-toggle/use-toggle.cjs.map +1 -1
  77. package/cjs/use-uncontrolled/use-uncontrolled.cjs.map +1 -1
  78. package/cjs/use-validated-state/use-validated-state.cjs.map +1 -1
  79. package/cjs/use-viewport-size/use-viewport-size.cjs.map +1 -1
  80. package/cjs/use-window-event/use-window-event.cjs.map +1 -1
  81. package/cjs/use-window-scroll/use-window-scroll.cjs.map +1 -1
  82. package/cjs/utils/use-callback-ref/use-callback-ref.cjs.map +1 -1
  83. package/esm/use-hotkeys/parse-hotkey.mjs.map +1 -1
  84. package/esm/use-id/use-id.mjs +2 -1
  85. package/esm/use-id/use-id.mjs.map +1 -1
  86. package/esm/use-local-storage/create-storage.mjs.map +1 -1
  87. package/esm/use-long-press/use-long-press.mjs +2 -1
  88. package/esm/use-long-press/use-long-press.mjs.map +1 -1
  89. package/esm/use-mask/use-mask.mjs +9 -7
  90. package/esm/use-mask/use-mask.mjs.map +1 -1
  91. package/esm/use-roving-index/use-roving-index.mjs +11 -14
  92. package/esm/use-roving-index/use-roving-index.mjs.map +1 -1
  93. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"use-roving-index.cjs","names":["useUncontrolled"],"sources":["../../src/use-roving-index/use-roving-index.ts"],"sourcesContent":["import { useCallback, useEffect, useRef } from 'react';\nimport { useUncontrolled } from '../use-uncontrolled/use-uncontrolled';\n\nexport interface UseRovingIndexInput {\n /** Total number of items in the group */\n total: number;\n\n /** Which arrow keys navigate, `'horizontal'` by default */\n orientation?: 'horizontal' | 'vertical' | 'both';\n\n /** Whether navigation wraps at boundaries, `true` by default */\n loop?: boolean;\n\n /** Text direction, `'ltr'` by default */\n dir?: 'rtl' | 'ltr';\n\n /** Whether to click element when it receives focus via keyboard, `false` by default */\n activateOnFocus?: boolean;\n\n /** Number of columns for grid (2D) navigation. When set, enables grid mode */\n columns?: number;\n\n /** Controlled focused index */\n focusedIndex?: number;\n\n /** Initial focused index for uncontrolled mode, first non-disabled item by default */\n initialIndex?: number;\n\n /** Called when focused index changes */\n onFocusChange?: (index: number) => void;\n\n /** Function to check if item at given index is disabled, `() => false` by default */\n isItemDisabled?: (index: number) => boolean;\n}\n\nexport interface UseRovingIndexGetItemPropsInput {\n /** Index of the item in the group */\n index: number;\n\n /** Called when item is clicked */\n onClick?: React.MouseEventHandler;\n\n /** Called when keydown event fires on item */\n onKeyDown?: React.KeyboardEventHandler;\n}\n\nexport interface UseRovingIndexReturnValue {\n /** Get props to spread on each navigable item */\n getItemProps: (options: UseRovingIndexGetItemPropsInput) => {\n tabIndex: 0 | -1;\n onKeyDown: React.KeyboardEventHandler;\n onClick: React.MouseEventHandler;\n ref: React.RefCallback<HTMLElement>;\n };\n\n /** Currently focused index */\n focusedIndex: number;\n\n /** Programmatically set focused index */\n setFocusedIndex: (index: number) => void;\n}\n\nfunction findNextEnabled(\n current: number,\n total: number,\n isItemDisabled: (index: number) => boolean,\n loop: boolean\n): number {\n for (let i = current + 1; i < total; i += 1) {\n if (!isItemDisabled(i)) {\n return i;\n }\n }\n\n if (loop) {\n for (let i = 0; i < current; i += 1) {\n if (!isItemDisabled(i)) {\n return i;\n }\n }\n }\n\n return current;\n}\n\nfunction findPreviousEnabled(\n current: number,\n total: number,\n isItemDisabled: (index: number) => boolean,\n loop: boolean\n): number {\n for (let i = current - 1; i >= 0; i -= 1) {\n if (!isItemDisabled(i)) {\n return i;\n }\n }\n\n if (loop) {\n for (let i = total - 1; i > current; i -= 1) {\n if (!isItemDisabled(i)) {\n return i;\n }\n }\n }\n\n return current;\n}\n\nfunction findFirstEnabled(total: number, isItemDisabled: (index: number) => boolean): number {\n for (let i = 0; i < total; i += 1) {\n if (!isItemDisabled(i)) {\n return i;\n }\n }\n\n return 0;\n}\n\nfunction findLastEnabled(total: number, isItemDisabled: (index: number) => boolean): number {\n for (let i = total - 1; i >= 0; i -= 1) {\n if (!isItemDisabled(i)) {\n return i;\n }\n }\n\n return 0;\n}\n\nconst defaultIsItemDisabled = () => false;\n\nexport function useRovingIndex(input: UseRovingIndexInput): UseRovingIndexReturnValue {\n const {\n total,\n orientation = 'horizontal',\n loop = true,\n dir = 'ltr',\n activateOnFocus = false,\n columns,\n focusedIndex,\n initialIndex,\n onFocusChange,\n isItemDisabled = defaultIsItemDisabled,\n } = input;\n\n const itemRefs = useRef<Map<number, HTMLElement>>(new Map());\n const isGrid = typeof columns === 'number' && columns > 0;\n\n const resolvedInitialIndex =\n initialIndex !== undefined ? initialIndex : findFirstEnabled(total, isItemDisabled);\n\n const [activeIndex, setActiveIndex] = useUncontrolled({\n value: focusedIndex,\n defaultValue: resolvedInitialIndex,\n finalValue: 0,\n onChange: onFocusChange,\n });\n\n useEffect(() => {\n if (total === 0) {\n return;\n }\n\n if (activeIndex >= total) {\n setActiveIndex(findLastEnabled(total, isItemDisabled));\n } else if (isItemDisabled(activeIndex)) {\n setActiveIndex(findFirstEnabled(total, isItemDisabled));\n }\n }, [total, activeIndex, isItemDisabled]);\n\n const focusItem = useCallback(\n (index: number) => {\n setActiveIndex(index);\n const element = itemRefs.current.get(index);\n if (element) {\n element.focus();\n if (activateOnFocus) {\n element.click();\n }\n }\n },\n [activateOnFocus, setActiveIndex]\n );\n\n const handleGridKeyDown = useCallback(\n (event: React.KeyboardEvent, currentIndex: number) => {\n const row = Math.floor(currentIndex / columns!);\n const col = currentIndex % columns!;\n const totalRows = Math.ceil(total / columns!);\n let nextIndex: number | null = null;\n\n const isRtl = dir === 'rtl';\n\n switch (event.key) {\n case 'ArrowRight': {\n const targetCol = isRtl ? col - 1 : col + 1;\n if (targetCol >= 0 && targetCol < columns! && row * columns! + targetCol < total) {\n const candidate = row * columns! + targetCol;\n if (!isItemDisabled(candidate)) {\n nextIndex = candidate;\n }\n }\n break;\n }\n\n case 'ArrowLeft': {\n const targetCol = isRtl ? col + 1 : col - 1;\n if (targetCol >= 0 && targetCol < columns! && row * columns! + targetCol < total) {\n const candidate = row * columns! + targetCol;\n if (!isItemDisabled(candidate)) {\n nextIndex = candidate;\n }\n }\n break;\n }\n\n case 'ArrowDown': {\n for (let r = row + 1; r < totalRows; r += 1) {\n const candidate = r * columns! + col;\n if (candidate < total && !isItemDisabled(candidate)) {\n nextIndex = candidate;\n break;\n }\n }\n break;\n }\n\n case 'ArrowUp': {\n for (let r = row - 1; r >= 0; r -= 1) {\n const candidate = r * columns! + col;\n if (candidate < total && !isItemDisabled(candidate)) {\n nextIndex = candidate;\n break;\n }\n }\n break;\n }\n\n case 'Home': {\n if (event.ctrlKey) {\n nextIndex = findFirstEnabled(total, isItemDisabled);\n } else {\n const rowStart = row * columns!;\n for (let i = rowStart; i < rowStart + columns! && i < total; i += 1) {\n if (!isItemDisabled(i)) {\n nextIndex = i;\n break;\n }\n }\n }\n break;\n }\n\n case 'End': {\n if (event.ctrlKey) {\n nextIndex = findLastEnabled(total, isItemDisabled);\n } else {\n const rowStart = row * columns!;\n const rowEnd = Math.min(rowStart + columns!, total) - 1;\n for (let i = rowEnd; i >= rowStart; i -= 1) {\n if (!isItemDisabled(i)) {\n nextIndex = i;\n break;\n }\n }\n }\n break;\n }\n }\n\n if (nextIndex !== null && nextIndex !== currentIndex) {\n event.preventDefault();\n event.stopPropagation();\n focusItem(nextIndex);\n }\n },\n [total, columns, dir, isItemDisabled, focusItem]\n );\n\n const handleListKeyDown = useCallback(\n (event: React.KeyboardEvent, currentIndex: number) => {\n const isRtl = dir === 'rtl';\n let nextIndex: number | null = null;\n\n switch (event.key) {\n case 'ArrowRight': {\n if (orientation === 'horizontal' || orientation === 'both') {\n nextIndex = isRtl\n ? findPreviousEnabled(currentIndex, total, isItemDisabled, loop)\n : findNextEnabled(currentIndex, total, isItemDisabled, loop);\n }\n break;\n }\n\n case 'ArrowLeft': {\n if (orientation === 'horizontal' || orientation === 'both') {\n nextIndex = isRtl\n ? findNextEnabled(currentIndex, total, isItemDisabled, loop)\n : findPreviousEnabled(currentIndex, total, isItemDisabled, loop);\n }\n break;\n }\n\n case 'ArrowDown': {\n if (orientation === 'vertical' || orientation === 'both') {\n nextIndex = findNextEnabled(currentIndex, total, isItemDisabled, loop);\n }\n break;\n }\n\n case 'ArrowUp': {\n if (orientation === 'vertical' || orientation === 'both') {\n nextIndex = findPreviousEnabled(currentIndex, total, isItemDisabled, loop);\n }\n break;\n }\n\n case 'Home': {\n nextIndex = findFirstEnabled(total, isItemDisabled);\n break;\n }\n\n case 'End': {\n nextIndex = findLastEnabled(total, isItemDisabled);\n break;\n }\n }\n\n if (nextIndex !== null && nextIndex !== currentIndex) {\n event.preventDefault();\n event.stopPropagation();\n focusItem(nextIndex);\n }\n },\n [total, orientation, loop, dir, isItemDisabled, focusItem]\n );\n\n const getItemProps = useCallback(\n (options: UseRovingIndexGetItemPropsInput) => {\n const { index, onClick, onKeyDown } = options;\n\n return {\n tabIndex: (index === activeIndex ? 0 : -1) as 0 | -1,\n\n ref: (node: HTMLElement | null) => {\n if (node) {\n itemRefs.current.set(index, node);\n } else {\n itemRefs.current.delete(index);\n }\n },\n\n onKeyDown: (event: React.KeyboardEvent) => {\n onKeyDown?.(event);\n\n if (event.defaultPrevented) {\n return;\n }\n\n if (isGrid) {\n handleGridKeyDown(event, index);\n } else {\n handleListKeyDown(event, index);\n }\n },\n\n onClick: (event: React.MouseEvent) => {\n onClick?.(event);\n setActiveIndex(index);\n },\n };\n },\n [activeIndex, isGrid, handleGridKeyDown, handleListKeyDown, setActiveIndex]\n );\n\n return {\n getItemProps,\n focusedIndex: activeIndex,\n setFocusedIndex: setActiveIndex,\n };\n}\n\nexport namespace useRovingIndex {\n export type Input = UseRovingIndexInput;\n export type GetItemPropsInput = UseRovingIndexGetItemPropsInput;\n export type ReturnValue = UseRovingIndexReturnValue;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"use-roving-index.cjs","names":["useRef","useUncontrolled","useCallback"],"sources":["../../src/use-roving-index/use-roving-index.ts"],"sourcesContent":["import { useCallback, useEffect, useRef } from 'react';\nimport { useUncontrolled } from '../use-uncontrolled/use-uncontrolled';\n\nexport interface UseRovingIndexInput {\n /** Total number of items in the group */\n total: number;\n\n /** Which arrow keys navigate, `'horizontal'` by default */\n orientation?: 'horizontal' | 'vertical' | 'both';\n\n /** Whether navigation wraps at boundaries, `true` by default */\n loop?: boolean;\n\n /** Text direction, `'ltr'` by default */\n dir?: 'rtl' | 'ltr';\n\n /** Whether to click element when it receives focus via keyboard, `false` by default */\n activateOnFocus?: boolean;\n\n /** Number of columns for grid (2D) navigation. When set, enables grid mode */\n columns?: number;\n\n /** Controlled focused index */\n focusedIndex?: number;\n\n /** Initial focused index for uncontrolled mode, first non-disabled item by default */\n initialIndex?: number;\n\n /** Called when focused index changes */\n onFocusChange?: (index: number) => void;\n\n /** Function to check if item at given index is disabled, `() => false` by default */\n isItemDisabled?: (index: number) => boolean;\n}\n\nexport interface UseRovingIndexGetItemPropsInput {\n /** Index of the item in the group */\n index: number;\n\n /** Called when item is clicked */\n onClick?: React.MouseEventHandler;\n\n /** Called when keydown event fires on item */\n onKeyDown?: React.KeyboardEventHandler;\n}\n\nexport interface UseRovingIndexReturnValue {\n /** Get props to spread on each navigable item */\n getItemProps: (options: UseRovingIndexGetItemPropsInput) => {\n tabIndex: 0 | -1;\n onKeyDown: React.KeyboardEventHandler;\n onClick: React.MouseEventHandler;\n ref: React.RefCallback<HTMLElement>;\n };\n\n /** Currently focused index */\n focusedIndex: number;\n\n /** Programmatically set focused index */\n setFocusedIndex: (index: number) => void;\n}\n\nfunction findNextEnabled(\n current: number,\n total: number,\n isItemDisabled: (index: number) => boolean,\n loop: boolean\n): number {\n for (let i = current + 1; i < total; i += 1) {\n if (!isItemDisabled(i)) {\n return i;\n }\n }\n\n if (loop) {\n for (let i = 0; i < current; i += 1) {\n if (!isItemDisabled(i)) {\n return i;\n }\n }\n }\n\n return current;\n}\n\nfunction findPreviousEnabled(\n current: number,\n total: number,\n isItemDisabled: (index: number) => boolean,\n loop: boolean\n): number {\n for (let i = current - 1; i >= 0; i -= 1) {\n if (!isItemDisabled(i)) {\n return i;\n }\n }\n\n if (loop) {\n for (let i = total - 1; i > current; i -= 1) {\n if (!isItemDisabled(i)) {\n return i;\n }\n }\n }\n\n return current;\n}\n\nfunction findFirstEnabled(total: number, isItemDisabled: (index: number) => boolean): number {\n for (let i = 0; i < total; i += 1) {\n if (!isItemDisabled(i)) {\n return i;\n }\n }\n\n return 0;\n}\n\nfunction findLastEnabled(total: number, isItemDisabled: (index: number) => boolean): number {\n for (let i = total - 1; i >= 0; i -= 1) {\n if (!isItemDisabled(i)) {\n return i;\n }\n }\n\n return 0;\n}\n\nconst defaultIsItemDisabled = () => false;\n\nexport function useRovingIndex(input: UseRovingIndexInput): UseRovingIndexReturnValue {\n const {\n total,\n orientation = 'horizontal',\n loop = true,\n dir = 'ltr',\n activateOnFocus = false,\n columns,\n focusedIndex,\n initialIndex,\n onFocusChange,\n isItemDisabled = defaultIsItemDisabled,\n } = input;\n\n const itemRefs = useRef<Map<number, HTMLElement>>(new Map());\n const isGrid = typeof columns === 'number' && columns > 0;\n\n const resolvedInitialIndex =\n initialIndex !== undefined ? initialIndex : findFirstEnabled(total, isItemDisabled);\n\n const [activeIndex, setActiveIndex] = useUncontrolled({\n value: focusedIndex,\n defaultValue: resolvedInitialIndex,\n finalValue: 0,\n onChange: onFocusChange,\n });\n\n useEffect(() => {\n if (total === 0) {\n return;\n }\n\n if (activeIndex >= total) {\n setActiveIndex(findLastEnabled(total, isItemDisabled));\n } else if (isItemDisabled(activeIndex)) {\n setActiveIndex(findFirstEnabled(total, isItemDisabled));\n }\n }, [total, activeIndex, isItemDisabled]);\n\n const focusItem = useCallback(\n (index: number) => {\n setActiveIndex(index);\n const element = itemRefs.current.get(index);\n if (element) {\n element.focus();\n if (activateOnFocus) {\n element.click();\n }\n }\n },\n [activateOnFocus, setActiveIndex]\n );\n\n const handleGridKeyDown = useCallback(\n (event: React.KeyboardEvent, currentIndex: number) => {\n const row = Math.floor(currentIndex / columns!);\n const col = currentIndex % columns!;\n const totalRows = Math.ceil(total / columns!);\n let nextIndex: number | null = null;\n\n const isRtl = dir === 'rtl';\n\n switch (event.key) {\n case 'ArrowRight': {\n const targetCol = isRtl ? col - 1 : col + 1;\n if (targetCol >= 0 && targetCol < columns! && row * columns! + targetCol < total) {\n const candidate = row * columns! + targetCol;\n if (!isItemDisabled(candidate)) {\n nextIndex = candidate;\n }\n }\n break;\n }\n\n case 'ArrowLeft': {\n const targetCol = isRtl ? col + 1 : col - 1;\n if (targetCol >= 0 && targetCol < columns! && row * columns! + targetCol < total) {\n const candidate = row * columns! + targetCol;\n if (!isItemDisabled(candidate)) {\n nextIndex = candidate;\n }\n }\n break;\n }\n\n case 'ArrowDown': {\n for (let r = row + 1; r < totalRows; r += 1) {\n const candidate = r * columns! + col;\n if (candidate < total && !isItemDisabled(candidate)) {\n nextIndex = candidate;\n break;\n }\n }\n break;\n }\n\n case 'ArrowUp': {\n for (let r = row - 1; r >= 0; r -= 1) {\n const candidate = r * columns! + col;\n if (candidate < total && !isItemDisabled(candidate)) {\n nextIndex = candidate;\n break;\n }\n }\n break;\n }\n\n case 'Home': {\n if (event.ctrlKey) {\n nextIndex = findFirstEnabled(total, isItemDisabled);\n } else {\n const rowStart = row * columns!;\n for (let i = rowStart; i < rowStart + columns! && i < total; i += 1) {\n if (!isItemDisabled(i)) {\n nextIndex = i;\n break;\n }\n }\n }\n break;\n }\n\n case 'End': {\n if (event.ctrlKey) {\n nextIndex = findLastEnabled(total, isItemDisabled);\n } else {\n const rowStart = row * columns!;\n const rowEnd = Math.min(rowStart + columns!, total) - 1;\n for (let i = rowEnd; i >= rowStart; i -= 1) {\n if (!isItemDisabled(i)) {\n nextIndex = i;\n break;\n }\n }\n }\n break;\n }\n }\n\n if (nextIndex !== null && nextIndex !== currentIndex) {\n event.preventDefault();\n event.stopPropagation();\n focusItem(nextIndex);\n }\n },\n [total, columns, dir, isItemDisabled, focusItem]\n );\n\n const handleListKeyDown = useCallback(\n (event: React.KeyboardEvent, currentIndex: number) => {\n const isRtl = dir === 'rtl';\n let nextIndex: number | null = null;\n\n switch (event.key) {\n case 'ArrowRight': {\n if (orientation === 'horizontal' || orientation === 'both') {\n nextIndex = isRtl\n ? findPreviousEnabled(currentIndex, total, isItemDisabled, loop)\n : findNextEnabled(currentIndex, total, isItemDisabled, loop);\n }\n break;\n }\n\n case 'ArrowLeft': {\n if (orientation === 'horizontal' || orientation === 'both') {\n nextIndex = isRtl\n ? findNextEnabled(currentIndex, total, isItemDisabled, loop)\n : findPreviousEnabled(currentIndex, total, isItemDisabled, loop);\n }\n break;\n }\n\n case 'ArrowDown': {\n if (orientation === 'vertical' || orientation === 'both') {\n nextIndex = findNextEnabled(currentIndex, total, isItemDisabled, loop);\n }\n break;\n }\n\n case 'ArrowUp': {\n if (orientation === 'vertical' || orientation === 'both') {\n nextIndex = findPreviousEnabled(currentIndex, total, isItemDisabled, loop);\n }\n break;\n }\n\n case 'Home': {\n nextIndex = findFirstEnabled(total, isItemDisabled);\n break;\n }\n\n case 'End': {\n nextIndex = findLastEnabled(total, isItemDisabled);\n break;\n }\n }\n\n if (nextIndex !== null && nextIndex !== currentIndex) {\n event.preventDefault();\n event.stopPropagation();\n focusItem(nextIndex);\n }\n },\n [total, orientation, loop, dir, isItemDisabled, focusItem]\n );\n\n const getItemProps = useCallback(\n (options: UseRovingIndexGetItemPropsInput) => {\n const { index, onClick, onKeyDown } = options;\n\n return {\n tabIndex: (index === activeIndex ? 0 : -1) as 0 | -1,\n\n ref: (node: HTMLElement | null) => {\n if (node) {\n itemRefs.current.set(index, node);\n } else {\n itemRefs.current.delete(index);\n }\n },\n\n onKeyDown: (event: React.KeyboardEvent) => {\n onKeyDown?.(event);\n\n if (event.defaultPrevented) {\n return;\n }\n\n if (isGrid) {\n handleGridKeyDown(event, index);\n } else {\n handleListKeyDown(event, index);\n }\n },\n\n onClick: (event: React.MouseEvent) => {\n onClick?.(event);\n setActiveIndex(index);\n },\n };\n },\n [activeIndex, isGrid, handleGridKeyDown, handleListKeyDown, setActiveIndex]\n );\n\n return {\n getItemProps,\n focusedIndex: activeIndex,\n setFocusedIndex: setActiveIndex,\n };\n}\n\nexport namespace useRovingIndex {\n export type Input = UseRovingIndexInput;\n export type GetItemPropsInput = UseRovingIndexGetItemPropsInput;\n export type ReturnValue = UseRovingIndexReturnValue;\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"use-scroll-direction.cjs","names":[],"sources":["../../src/use-scroll-direction/use-scroll-direction.ts"],"sourcesContent":["import { useEffect, useEffectEvent, useRef, useState } from 'react';\n\nexport type ScrollDirection = 'up' | 'down' | 'unknown';\n\nexport function useScrollDirection(): ScrollDirection {\n const lastScrollTopRef = useRef(0);\n const [scrollDirection, setScrollDirection] = useState<ScrollDirection>('unknown');\n const isResizingRef = useRef(false);\n const resizeTimerRef = useRef<number | undefined>(undefined);\n\n const handleScroll = useEffectEvent(() => {\n if (isResizingRef.current) {\n return;\n }\n\n const currentScrollTop = window.scrollY || document.documentElement.scrollTop;\n setScrollDirection(currentScrollTop < lastScrollTopRef.current ? 'up' : 'down');\n lastScrollTopRef.current = currentScrollTop;\n });\n\n useEffect(() => {\n const handleResize = () => {\n isResizingRef.current = true;\n window.clearTimeout(resizeTimerRef.current);\n resizeTimerRef.current = window.setTimeout(() => {\n isResizingRef.current = false;\n }, 300);\n };\n\n window.addEventListener('scroll', handleScroll);\n window.addEventListener('resize', handleResize);\n\n return () => {\n window.removeEventListener('scroll', handleScroll);\n window.removeEventListener('resize', handleResize);\n clearTimeout(resizeTimerRef.current);\n };\n }, []);\n\n return scrollDirection;\n}\n"],"mappings":";;;AAIA,SAAgB,qBAAsC;CACpD,MAAM,oBAAA,GAAA,MAAA,OAAA,CAA0B,CAAC;CACjC,MAAM,CAAC,iBAAiB,uBAAA,GAAA,MAAA,SAAA,CAAgD,SAAS;CACjF,MAAM,iBAAA,GAAA,MAAA,OAAA,CAAuB,KAAK;CAClC,MAAM,kBAAA,GAAA,MAAA,OAAA,CAA4C,KAAA,CAAS;CAE3D,MAAM,gBAAA,GAAA,MAAA,eAAA,OAAoC;EACxC,IAAI,cAAc,SAChB;EAGF,MAAM,mBAAmB,OAAO,WAAW,SAAS,gBAAgB;EACpE,mBAAmB,mBAAmB,iBAAiB,UAAU,OAAO,MAAM;EAC9E,iBAAiB,UAAU;CAC7B,CAAC;CAED,CAAA,GAAA,MAAA,UAAA,OAAgB;EACd,MAAM,qBAAqB;GACzB,cAAc,UAAU;GACxB,OAAO,aAAa,eAAe,OAAO;GAC1C,eAAe,UAAU,OAAO,iBAAiB;IAC/C,cAAc,UAAU;GAC1B,GAAG,GAAG;EACR;EAEA,OAAO,iBAAiB,UAAU,YAAY;EAC9C,OAAO,iBAAiB,UAAU,YAAY;EAE9C,aAAa;GACX,OAAO,oBAAoB,UAAU,YAAY;GACjD,OAAO,oBAAoB,UAAU,YAAY;GACjD,aAAa,eAAe,OAAO;EACrC;CACF,GAAG,CAAC,CAAC;CAEL,OAAO;AACT"}
1
+ {"version":3,"file":"use-scroll-direction.cjs","names":["useRef","useState","useEffectEvent"],"sources":["../../src/use-scroll-direction/use-scroll-direction.ts"],"sourcesContent":["import { useEffect, useEffectEvent, useRef, useState } from 'react';\n\nexport type ScrollDirection = 'up' | 'down' | 'unknown';\n\nexport function useScrollDirection(): ScrollDirection {\n const lastScrollTopRef = useRef(0);\n const [scrollDirection, setScrollDirection] = useState<ScrollDirection>('unknown');\n const isResizingRef = useRef(false);\n const resizeTimerRef = useRef<number | undefined>(undefined);\n\n const handleScroll = useEffectEvent(() => {\n if (isResizingRef.current) {\n return;\n }\n\n const currentScrollTop = window.scrollY || document.documentElement.scrollTop;\n setScrollDirection(currentScrollTop < lastScrollTopRef.current ? 'up' : 'down');\n lastScrollTopRef.current = currentScrollTop;\n });\n\n useEffect(() => {\n const handleResize = () => {\n isResizingRef.current = true;\n window.clearTimeout(resizeTimerRef.current);\n resizeTimerRef.current = window.setTimeout(() => {\n isResizingRef.current = false;\n }, 300);\n };\n\n window.addEventListener('scroll', handleScroll);\n window.addEventListener('resize', handleResize);\n\n return () => {\n window.removeEventListener('scroll', handleScroll);\n window.removeEventListener('resize', handleResize);\n clearTimeout(resizeTimerRef.current);\n };\n }, []);\n\n return scrollDirection;\n}\n"],"mappings":";;;AAIA,SAAgB,qBAAsC;CACpD,MAAM,oBAAA,GAAmBA,MAAAA,OAAAA,CAAO,CAAC;CACjC,MAAM,CAAC,iBAAiB,uBAAA,GAAsBC,MAAAA,SAAAA,CAA0B,SAAS;CACjF,MAAM,iBAAA,GAAgBD,MAAAA,OAAAA,CAAO,KAAK;CAClC,MAAM,kBAAA,GAAiBA,MAAAA,OAAAA,CAA2B,KAAA,CAAS;CAE3D,MAAM,gBAAA,GAAeE,MAAAA,eAAAA,OAAqB;EACxC,IAAI,cAAc,SAChB;EAGF,MAAM,mBAAmB,OAAO,WAAW,SAAS,gBAAgB;EACpE,mBAAmB,mBAAmB,iBAAiB,UAAU,OAAO,MAAM;EAC9E,iBAAiB,UAAU;CAC7B,CAAC;CAED,CAAA,GAAA,MAAA,UAAA,OAAgB;EACd,MAAM,qBAAqB;GACzB,cAAc,UAAU;GACxB,OAAO,aAAa,eAAe,OAAO;GAC1C,eAAe,UAAU,OAAO,iBAAiB;IAC/C,cAAc,UAAU;GAC1B,GAAG,GAAG;EACR;EAEA,OAAO,iBAAiB,UAAU,YAAY;EAC9C,OAAO,iBAAiB,UAAU,YAAY;EAE9C,aAAa;GACX,OAAO,oBAAoB,UAAU,YAAY;GACjD,OAAO,oBAAoB,UAAU,YAAY;GACjD,aAAa,eAAe,OAAO;EACrC;CACF,GAAG,CAAC,CAAC;CAEL,OAAO;AACT"}
@@ -1 +1 @@
1
- {"version":3,"file":"use-scroll-into-view.cjs","names":["useReducedMotion"],"sources":["../../src/use-scroll-into-view/use-scroll-into-view.ts"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from 'react';\nimport { useReducedMotion } from '../use-reduced-motion/use-reduced-motion';\nimport { useWindowEvent } from '../use-window-event/use-window-event';\n\ninterface UseScrollIntoViewAnimation {\n /** Target element alignment relatively to parent based on current axis */\n alignment?: 'start' | 'end' | 'center';\n}\n\nexport interface UseScrollIntoViewOptions {\n /** Callback fired after scroll */\n onScrollFinish?: () => void;\n\n /** Callback fired when scroll animation is canceled by user interaction */\n onScrollCancel?: () => void;\n\n /** Duration of scroll in milliseconds */\n duration?: number;\n\n /** Axis of scroll */\n axis?: 'x' | 'y';\n\n /** Custom mathematical easing function */\n easing?: (t: number) => number;\n\n /** Additional distance between nearest edge and element */\n offset?: number;\n\n /** Indicator if animation may be interrupted by user scrolling */\n cancelable?: boolean;\n\n /** Prevents content jumping in scrolling lists with multiple targets */\n isList?: boolean;\n}\n\nexport interface UseScrollIntoViewReturnValue<\n Target extends HTMLElement = any,\n Parent extends HTMLElement | null = null,\n> {\n scrollableRef: React.RefObject<Parent | null>;\n targetRef: React.RefObject<Target | null>;\n scrollIntoView: (params?: UseScrollIntoViewAnimation) => void;\n cancel: () => void;\n scrolling: boolean;\n}\n\nexport function useScrollIntoView<\n Target extends HTMLElement = any,\n Parent extends HTMLElement | null = null,\n>({\n duration = 1250,\n axis = 'y',\n onScrollFinish,\n onScrollCancel,\n easing,\n offset = 0,\n cancelable = true,\n isList = false,\n}: UseScrollIntoViewOptions = {}): UseScrollIntoViewReturnValue<Target, Parent> {\n const frameID = useRef(0);\n const startTime = useRef(0);\n const shouldStop = useRef(false);\n const [scrolling, setScrolling] = useState(false);\n\n const scrollableRef = useRef<Parent | null>(null);\n const targetRef = useRef<Target | null>(null);\n\n const reducedMotion = useReducedMotion();\n\n const _easing = easing ?? easeInOutQuad;\n\n const cancel = (): void => {\n if (frameID.current) {\n cancelAnimationFrame(frameID.current);\n frameID.current = 0;\n setScrolling(false);\n }\n };\n\n const scrollIntoView = useCallback(\n ({ alignment = 'start' }: UseScrollIntoViewAnimation = {}) => {\n shouldStop.current = false;\n\n if (frameID.current) {\n cancel();\n }\n\n const start = getScrollStart({ parent: scrollableRef.current, axis }) ?? 0;\n\n const change =\n getRelativePosition({\n parent: scrollableRef.current,\n target: targetRef.current,\n axis,\n alignment,\n offset,\n isList,\n }) - (scrollableRef.current ? 0 : start);\n\n setScrolling(true);\n\n function animateScroll() {\n if (startTime.current === 0) {\n startTime.current = performance.now();\n }\n\n const now = performance.now();\n const elapsed = now - startTime.current;\n\n // Easing timing progress\n const t = reducedMotion || duration === 0 ? 1 : elapsed / duration;\n\n const distance = start + change * _easing(t);\n\n setScrollParam({\n parent: scrollableRef.current,\n axis,\n distance,\n });\n\n if (!shouldStop.current && t < 1) {\n frameID.current = requestAnimationFrame(animateScroll);\n } else {\n if (shouldStop.current) {\n typeof onScrollCancel === 'function' && onScrollCancel();\n } else {\n typeof onScrollFinish === 'function' && onScrollFinish();\n }\n startTime.current = 0;\n frameID.current = 0;\n setScrolling(false);\n cancel();\n }\n }\n animateScroll();\n },\n [axis, duration, _easing, isList, offset, onScrollFinish, onScrollCancel, reducedMotion]\n );\n\n const handleStop = () => {\n if (cancelable) {\n shouldStop.current = true;\n }\n };\n\n /**\n * Detection of one of these events stops scroll animation\n * wheel - mouse wheel / touch pad\n * touchmove - any touchable device\n */\n\n useWindowEvent('wheel', handleStop, {\n passive: true,\n });\n\n useWindowEvent('touchmove', handleStop, {\n passive: true,\n });\n\n // Cleanup requestAnimationFrame\n useEffect(() => cancel, []);\n\n return {\n scrollableRef,\n targetRef,\n scrollIntoView,\n cancel,\n scrolling,\n };\n}\n\n// ---------------------------------------------------\n// Helpers\n// ---------------------------------------------------\n\nfunction easeInOutQuad(t: number) {\n return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;\n}\n\nfunction getRelativePosition({ axis, target, parent, alignment, offset, isList }: any): number {\n if (!target || (!parent && typeof document === 'undefined')) {\n return 0;\n }\n const isCustomParent = !!parent;\n const parentElement = parent || document.body;\n const parentPosition = parentElement.getBoundingClientRect();\n const targetPosition = target.getBoundingClientRect();\n\n const getDiff = (property: 'top' | 'left'): number =>\n targetPosition[property] - parentPosition[property];\n\n if (axis === 'y') {\n const diff = getDiff('top');\n\n if (diff === 0) {\n return 0;\n }\n\n if (alignment === 'start') {\n const distance = diff - offset;\n const shouldScroll = distance <= targetPosition.height * (isList ? 0 : 1) || !isList;\n\n return shouldScroll ? distance : 0;\n }\n\n const parentHeight = isCustomParent ? parentPosition.height : window.innerHeight;\n\n if (alignment === 'end') {\n const distance = diff + offset - parentHeight + targetPosition.height;\n const shouldScroll = distance >= -targetPosition.height * (isList ? 0 : 1) || !isList;\n\n return shouldScroll ? distance : 0;\n }\n\n if (alignment === 'center') {\n return diff - parentHeight / 2 + targetPosition.height / 2;\n }\n\n return 0;\n }\n\n if (axis === 'x') {\n const diff = getDiff('left');\n\n if (diff === 0) {\n return 0;\n }\n\n if (alignment === 'start') {\n const distance = diff - offset;\n const shouldScroll = distance <= targetPosition.width || !isList;\n\n return shouldScroll ? distance : 0;\n }\n\n const parentWidth = isCustomParent ? parentPosition.width : window.innerWidth;\n\n if (alignment === 'end') {\n const distance = diff + offset - parentWidth + targetPosition.width;\n const shouldScroll = distance >= -targetPosition.width || !isList;\n\n return shouldScroll ? distance : 0;\n }\n\n if (alignment === 'center') {\n return diff - parentWidth / 2 + targetPosition.width / 2;\n }\n\n return 0;\n }\n\n return 0;\n}\n\nfunction getScrollStart({ axis, parent }: any) {\n if (!parent && typeof document === 'undefined') {\n return 0;\n }\n\n const method = axis === 'y' ? 'scrollTop' : 'scrollLeft';\n\n if (parent) {\n return parent[method];\n }\n\n const { body, documentElement } = document;\n\n // While one of it has a value the second is equal 0\n return body[method] + documentElement[method];\n}\n\nfunction setScrollParam({ axis, parent, distance }: any) {\n if (!parent && typeof document === 'undefined') {\n return;\n }\n\n const method = axis === 'y' ? 'scrollTop' : 'scrollLeft';\n\n if (parent) {\n parent[method] = distance;\n } else {\n const { body, documentElement } = document;\n body[method] = distance;\n documentElement[method] = distance;\n }\n}\n\nexport namespace useScrollIntoView {\n export type Options = UseScrollIntoViewOptions;\n export type ReturnValue<\n Target extends HTMLElement,\n Parent extends HTMLElement | null,\n > = UseScrollIntoViewReturnValue<Target, Parent>;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"use-scroll-into-view.cjs","names":["useRef","useState","useReducedMotion","useCallback"],"sources":["../../src/use-scroll-into-view/use-scroll-into-view.ts"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from 'react';\nimport { useReducedMotion } from '../use-reduced-motion/use-reduced-motion';\nimport { useWindowEvent } from '../use-window-event/use-window-event';\n\ninterface UseScrollIntoViewAnimation {\n /** Target element alignment relatively to parent based on current axis */\n alignment?: 'start' | 'end' | 'center';\n}\n\nexport interface UseScrollIntoViewOptions {\n /** Callback fired after scroll */\n onScrollFinish?: () => void;\n\n /** Callback fired when scroll animation is canceled by user interaction */\n onScrollCancel?: () => void;\n\n /** Duration of scroll in milliseconds */\n duration?: number;\n\n /** Axis of scroll */\n axis?: 'x' | 'y';\n\n /** Custom mathematical easing function */\n easing?: (t: number) => number;\n\n /** Additional distance between nearest edge and element */\n offset?: number;\n\n /** Indicator if animation may be interrupted by user scrolling */\n cancelable?: boolean;\n\n /** Prevents content jumping in scrolling lists with multiple targets */\n isList?: boolean;\n}\n\nexport interface UseScrollIntoViewReturnValue<\n Target extends HTMLElement = any,\n Parent extends HTMLElement | null = null,\n> {\n scrollableRef: React.RefObject<Parent | null>;\n targetRef: React.RefObject<Target | null>;\n scrollIntoView: (params?: UseScrollIntoViewAnimation) => void;\n cancel: () => void;\n scrolling: boolean;\n}\n\nexport function useScrollIntoView<\n Target extends HTMLElement = any,\n Parent extends HTMLElement | null = null,\n>({\n duration = 1250,\n axis = 'y',\n onScrollFinish,\n onScrollCancel,\n easing,\n offset = 0,\n cancelable = true,\n isList = false,\n}: UseScrollIntoViewOptions = {}): UseScrollIntoViewReturnValue<Target, Parent> {\n const frameID = useRef(0);\n const startTime = useRef(0);\n const shouldStop = useRef(false);\n const [scrolling, setScrolling] = useState(false);\n\n const scrollableRef = useRef<Parent | null>(null);\n const targetRef = useRef<Target | null>(null);\n\n const reducedMotion = useReducedMotion();\n\n const _easing = easing ?? easeInOutQuad;\n\n const cancel = (): void => {\n if (frameID.current) {\n cancelAnimationFrame(frameID.current);\n frameID.current = 0;\n setScrolling(false);\n }\n };\n\n const scrollIntoView = useCallback(\n ({ alignment = 'start' }: UseScrollIntoViewAnimation = {}) => {\n shouldStop.current = false;\n\n if (frameID.current) {\n cancel();\n }\n\n const start = getScrollStart({ parent: scrollableRef.current, axis }) ?? 0;\n\n const change =\n getRelativePosition({\n parent: scrollableRef.current,\n target: targetRef.current,\n axis,\n alignment,\n offset,\n isList,\n }) - (scrollableRef.current ? 0 : start);\n\n setScrolling(true);\n\n function animateScroll() {\n if (startTime.current === 0) {\n startTime.current = performance.now();\n }\n\n const now = performance.now();\n const elapsed = now - startTime.current;\n\n // Easing timing progress\n const t = reducedMotion || duration === 0 ? 1 : elapsed / duration;\n\n const distance = start + change * _easing(t);\n\n setScrollParam({\n parent: scrollableRef.current,\n axis,\n distance,\n });\n\n if (!shouldStop.current && t < 1) {\n frameID.current = requestAnimationFrame(animateScroll);\n } else {\n if (shouldStop.current) {\n typeof onScrollCancel === 'function' && onScrollCancel();\n } else {\n typeof onScrollFinish === 'function' && onScrollFinish();\n }\n startTime.current = 0;\n frameID.current = 0;\n setScrolling(false);\n cancel();\n }\n }\n animateScroll();\n },\n [axis, duration, _easing, isList, offset, onScrollFinish, onScrollCancel, reducedMotion]\n );\n\n const handleStop = () => {\n if (cancelable) {\n shouldStop.current = true;\n }\n };\n\n /**\n * Detection of one of these events stops scroll animation\n * wheel - mouse wheel / touch pad\n * touchmove - any touchable device\n */\n\n useWindowEvent('wheel', handleStop, {\n passive: true,\n });\n\n useWindowEvent('touchmove', handleStop, {\n passive: true,\n });\n\n // Cleanup requestAnimationFrame\n useEffect(() => cancel, []);\n\n return {\n scrollableRef,\n targetRef,\n scrollIntoView,\n cancel,\n scrolling,\n };\n}\n\n// ---------------------------------------------------\n// Helpers\n// ---------------------------------------------------\n\nfunction easeInOutQuad(t: number) {\n return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;\n}\n\nfunction getRelativePosition({ axis, target, parent, alignment, offset, isList }: any): number {\n if (!target || (!parent && typeof document === 'undefined')) {\n return 0;\n }\n const isCustomParent = !!parent;\n const parentElement = parent || document.body;\n const parentPosition = parentElement.getBoundingClientRect();\n const targetPosition = target.getBoundingClientRect();\n\n const getDiff = (property: 'top' | 'left'): number =>\n targetPosition[property] - parentPosition[property];\n\n if (axis === 'y') {\n const diff = getDiff('top');\n\n if (diff === 0) {\n return 0;\n }\n\n if (alignment === 'start') {\n const distance = diff - offset;\n const shouldScroll = distance <= targetPosition.height * (isList ? 0 : 1) || !isList;\n\n return shouldScroll ? distance : 0;\n }\n\n const parentHeight = isCustomParent ? parentPosition.height : window.innerHeight;\n\n if (alignment === 'end') {\n const distance = diff + offset - parentHeight + targetPosition.height;\n const shouldScroll = distance >= -targetPosition.height * (isList ? 0 : 1) || !isList;\n\n return shouldScroll ? distance : 0;\n }\n\n if (alignment === 'center') {\n return diff - parentHeight / 2 + targetPosition.height / 2;\n }\n\n return 0;\n }\n\n if (axis === 'x') {\n const diff = getDiff('left');\n\n if (diff === 0) {\n return 0;\n }\n\n if (alignment === 'start') {\n const distance = diff - offset;\n const shouldScroll = distance <= targetPosition.width || !isList;\n\n return shouldScroll ? distance : 0;\n }\n\n const parentWidth = isCustomParent ? parentPosition.width : window.innerWidth;\n\n if (alignment === 'end') {\n const distance = diff + offset - parentWidth + targetPosition.width;\n const shouldScroll = distance >= -targetPosition.width || !isList;\n\n return shouldScroll ? distance : 0;\n }\n\n if (alignment === 'center') {\n return diff - parentWidth / 2 + targetPosition.width / 2;\n }\n\n return 0;\n }\n\n return 0;\n}\n\nfunction getScrollStart({ axis, parent }: any) {\n if (!parent && typeof document === 'undefined') {\n return 0;\n }\n\n const method = axis === 'y' ? 'scrollTop' : 'scrollLeft';\n\n if (parent) {\n return parent[method];\n }\n\n const { body, documentElement } = document;\n\n // While one of it has a value the second is equal 0\n return body[method] + documentElement[method];\n}\n\nfunction setScrollParam({ axis, parent, distance }: any) {\n if (!parent && typeof document === 'undefined') {\n return;\n }\n\n const method = axis === 'y' ? 'scrollTop' : 'scrollLeft';\n\n if (parent) {\n parent[method] = distance;\n } else {\n const { body, documentElement } = document;\n body[method] = distance;\n documentElement[method] = distance;\n }\n}\n\nexport namespace useScrollIntoView {\n export type Options = UseScrollIntoViewOptions;\n export type ReturnValue<\n Target extends HTMLElement,\n Parent extends HTMLElement | null,\n > = UseScrollIntoViewReturnValue<Target, Parent>;\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"use-scroll-spy.cjs","names":["randomId"],"sources":["../../src/use-scroll-spy/use-scroll-spy.ts"],"sourcesContent":["import React, { useEffect, useEffectEvent, useRef, useState } from 'react';\nimport { randomId } from '../utils';\n\nfunction getHeadingsData(\n headings: HTMLElement[],\n getDepth: (element: HTMLElement) => number,\n getValue: (element: HTMLElement) => string\n): UseScrollSpyHeadingData[] {\n const result: UseScrollSpyHeadingData[] = [];\n\n for (let i = 0; i < headings.length; i += 1) {\n const heading = headings[i];\n result.push({\n depth: getDepth(heading),\n value: getValue(heading),\n id: heading.id || randomId(),\n getNode: () => (heading.id ? document.getElementById(heading.id)! : heading),\n });\n }\n\n return result;\n}\n\nfunction getActiveElement(rects: DOMRect[], offset: number = 0) {\n if (rects.length === 0) {\n return -1;\n }\n\n const closest = rects.reduce(\n (acc, item, index) => {\n if (Math.abs(acc.position - offset) < Math.abs(item.y - offset)) {\n return acc;\n }\n\n return {\n index,\n position: item.y,\n };\n },\n { index: 0, position: rects[0].y }\n );\n\n return closest.index;\n}\n\nfunction getDefaultDepth(element: HTMLElement) {\n return Number(element.tagName[1]);\n}\n\nfunction getDefaultValue(element: HTMLElement) {\n return element.textContent || '';\n}\n\nfunction resolveScrollHost(\n scrollHost: HTMLElement | React.RefObject<HTMLElement | null> | undefined\n): HTMLElement | Window {\n if (!scrollHost) {\n return window;\n }\n\n if ('current' in scrollHost) {\n return scrollHost.current || window;\n }\n\n return scrollHost;\n}\n\nexport interface UseScrollSpyHeadingData {\n /** Heading depth, 1-6 */\n depth: number;\n\n /** Heading text content value */\n value: string;\n\n /** Heading id */\n id: string;\n\n /** Function to get heading node */\n getNode: () => HTMLElement;\n}\n\nexport interface UseScrollSpyOptions {\n /** Selector to get headings, `'h1, h2, h3, h4, h5, h6'` by default */\n selector?: string;\n\n /** A function to retrieve depth of heading, by default depth is calculated based on tag name */\n getDepth?: (element: HTMLElement) => number;\n\n /** A function to retrieve heading value, by default `element.textContent` is used */\n getValue?: (element: HTMLElement) => string;\n\n /** Host element or a ref to it to attach scroll event listener, if not provided, `window` is used */\n scrollHost?: HTMLElement | React.RefObject<HTMLElement | null>;\n\n /** Offset from the top of the viewport to use when determining the active heading, `0` by default */\n offset?: number;\n}\n\nexport interface UseScrollSpyReturnValue {\n /** Index of the active heading in the `data` array */\n active: number;\n\n /** Headings data. If not initialize, data is represented by an empty array. */\n data: UseScrollSpyHeadingData[];\n\n /** True if headings value have been retrieved from the DOM. */\n initialized: boolean;\n\n /** Function to update headings values after the parent component has mounted. */\n reinitialize: () => void;\n}\n\nexport function useScrollSpy({\n selector = 'h1, h2, h3, h4, h5, h6',\n getDepth = getDefaultDepth,\n getValue = getDefaultValue,\n offset = 0,\n scrollHost,\n}: UseScrollSpyOptions = {}): UseScrollSpyReturnValue {\n const [active, setActive] = useState(-1);\n const [initialized, setInitialized] = useState(false);\n const [data, setData] = useState<UseScrollSpyHeadingData[]>([]);\n const headingsRef = useRef<UseScrollSpyHeadingData[]>([]);\n\n const handleScroll = useEffectEvent(() => {\n setActive(\n getActiveElement(\n headingsRef.current.map((d) => d.getNode().getBoundingClientRect()),\n offset\n )\n );\n });\n\n const initialize = () => {\n const headings = getHeadingsData(\n Array.from(document.querySelectorAll(selector)),\n getDepth,\n getValue\n );\n headingsRef.current = headings;\n setInitialized(true);\n setData(headings);\n setActive(\n getActiveElement(\n headings.map((d) => d.getNode().getBoundingClientRect()),\n offset\n )\n );\n };\n\n useEffect(() => {\n initialize();\n const _scrollHost = resolveScrollHost(scrollHost);\n _scrollHost.addEventListener('scroll', handleScroll);\n return () => _scrollHost.removeEventListener('scroll', handleScroll);\n }, [scrollHost, selector, offset]);\n\n return {\n reinitialize: initialize,\n active,\n initialized,\n data,\n };\n}\n\nexport namespace useScrollSpy {\n export type Options = UseScrollSpyOptions;\n export type ReturnValue = UseScrollSpyReturnValue;\n}\n"],"mappings":";;;;AAGA,SAAS,gBACP,UACA,UACA,UAC2B;CAC3B,MAAM,SAAoC,CAAC;CAE3C,KAAK,IAAI,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK,GAAG;EAC3C,MAAM,UAAU,SAAS;EACzB,OAAO,KAAK;GACV,OAAO,SAAS,OAAO;GACvB,OAAO,SAAS,OAAO;GACvB,IAAI,QAAQ,MAAMA,kBAAAA,SAAS;GAC3B,eAAgB,QAAQ,KAAK,SAAS,eAAe,QAAQ,EAAE,IAAK;EACtE,CAAC;CACH;CAEA,OAAO;AACT;AAEA,SAAS,iBAAiB,OAAkB,SAAiB,GAAG;CAC9D,IAAI,MAAM,WAAW,GACnB,OAAO;CAiBT,OAdgB,MAAM,QACnB,KAAK,MAAM,UAAU;EACpB,IAAI,KAAK,IAAI,IAAI,WAAW,MAAM,IAAI,KAAK,IAAI,KAAK,IAAI,MAAM,GAC5D,OAAO;EAGT,OAAO;GACL;GACA,UAAU,KAAK;EACjB;CACF,GACA;EAAE,OAAO;EAAG,UAAU,MAAM,EAAE,CAAC;CAAE,CAGtB,CAAC,CAAC;AACjB;AAEA,SAAS,gBAAgB,SAAsB;CAC7C,OAAO,OAAO,QAAQ,QAAQ,EAAE;AAClC;AAEA,SAAS,gBAAgB,SAAsB;CAC7C,OAAO,QAAQ,eAAe;AAChC;AAEA,SAAS,kBACP,YACsB;CACtB,IAAI,CAAC,YACH,OAAO;CAGT,IAAI,aAAa,YACf,OAAO,WAAW,WAAW;CAG/B,OAAO;AACT;AA+CA,SAAgB,aAAa,EAC3B,WAAW,0BACX,WAAW,iBACX,WAAW,iBACX,SAAS,GACT,eACuB,CAAC,GAA4B;CACpD,MAAM,CAAC,QAAQ,cAAA,GAAA,MAAA,SAAA,CAAsB,EAAE;CACvC,MAAM,CAAC,aAAa,mBAAA,GAAA,MAAA,SAAA,CAA2B,KAAK;CACpD,MAAM,CAAC,MAAM,YAAA,GAAA,MAAA,SAAA,CAA+C,CAAC,CAAC;CAC9D,MAAM,eAAA,GAAA,MAAA,OAAA,CAAgD,CAAC,CAAC;CAExD,MAAM,gBAAA,GAAA,MAAA,eAAA,OAAoC;EACxC,UACE,iBACE,YAAY,QAAQ,KAAK,MAAM,EAAE,QAAQ,CAAC,CAAC,sBAAsB,CAAC,GAClE,MACF,CACF;CACF,CAAC;CAED,MAAM,mBAAmB;EACvB,MAAM,WAAW,gBACf,MAAM,KAAK,SAAS,iBAAiB,QAAQ,CAAC,GAC9C,UACA,QACF;EACA,YAAY,UAAU;EACtB,eAAe,IAAI;EACnB,QAAQ,QAAQ;EAChB,UACE,iBACE,SAAS,KAAK,MAAM,EAAE,QAAQ,CAAC,CAAC,sBAAsB,CAAC,GACvD,MACF,CACF;CACF;CAEA,CAAA,GAAA,MAAA,UAAA,OAAgB;EACd,WAAW;EACX,MAAM,cAAc,kBAAkB,UAAU;EAChD,YAAY,iBAAiB,UAAU,YAAY;EACnD,aAAa,YAAY,oBAAoB,UAAU,YAAY;CACrE,GAAG;EAAC;EAAY;EAAU;CAAM,CAAC;CAEjC,OAAO;EACL,cAAc;EACd;EACA;EACA;CACF;AACF"}
1
+ {"version":3,"file":"use-scroll-spy.cjs","names":["randomId","useState","useRef","useEffectEvent"],"sources":["../../src/use-scroll-spy/use-scroll-spy.ts"],"sourcesContent":["import React, { useEffect, useEffectEvent, useRef, useState } from 'react';\nimport { randomId } from '../utils';\n\nfunction getHeadingsData(\n headings: HTMLElement[],\n getDepth: (element: HTMLElement) => number,\n getValue: (element: HTMLElement) => string\n): UseScrollSpyHeadingData[] {\n const result: UseScrollSpyHeadingData[] = [];\n\n for (let i = 0; i < headings.length; i += 1) {\n const heading = headings[i];\n result.push({\n depth: getDepth(heading),\n value: getValue(heading),\n id: heading.id || randomId(),\n getNode: () => (heading.id ? document.getElementById(heading.id)! : heading),\n });\n }\n\n return result;\n}\n\nfunction getActiveElement(rects: DOMRect[], offset: number = 0) {\n if (rects.length === 0) {\n return -1;\n }\n\n const closest = rects.reduce(\n (acc, item, index) => {\n if (Math.abs(acc.position - offset) < Math.abs(item.y - offset)) {\n return acc;\n }\n\n return {\n index,\n position: item.y,\n };\n },\n { index: 0, position: rects[0].y }\n );\n\n return closest.index;\n}\n\nfunction getDefaultDepth(element: HTMLElement) {\n return Number(element.tagName[1]);\n}\n\nfunction getDefaultValue(element: HTMLElement) {\n return element.textContent || '';\n}\n\nfunction resolveScrollHost(\n scrollHost: HTMLElement | React.RefObject<HTMLElement | null> | undefined\n): HTMLElement | Window {\n if (!scrollHost) {\n return window;\n }\n\n if ('current' in scrollHost) {\n return scrollHost.current || window;\n }\n\n return scrollHost;\n}\n\nexport interface UseScrollSpyHeadingData {\n /** Heading depth, 1-6 */\n depth: number;\n\n /** Heading text content value */\n value: string;\n\n /** Heading id */\n id: string;\n\n /** Function to get heading node */\n getNode: () => HTMLElement;\n}\n\nexport interface UseScrollSpyOptions {\n /** Selector to get headings, `'h1, h2, h3, h4, h5, h6'` by default */\n selector?: string;\n\n /** A function to retrieve depth of heading, by default depth is calculated based on tag name */\n getDepth?: (element: HTMLElement) => number;\n\n /** A function to retrieve heading value, by default `element.textContent` is used */\n getValue?: (element: HTMLElement) => string;\n\n /** Host element or a ref to it to attach scroll event listener, if not provided, `window` is used */\n scrollHost?: HTMLElement | React.RefObject<HTMLElement | null>;\n\n /** Offset from the top of the viewport to use when determining the active heading, `0` by default */\n offset?: number;\n}\n\nexport interface UseScrollSpyReturnValue {\n /** Index of the active heading in the `data` array */\n active: number;\n\n /** Headings data. If not initialize, data is represented by an empty array. */\n data: UseScrollSpyHeadingData[];\n\n /** True if headings value have been retrieved from the DOM. */\n initialized: boolean;\n\n /** Function to update headings values after the parent component has mounted. */\n reinitialize: () => void;\n}\n\nexport function useScrollSpy({\n selector = 'h1, h2, h3, h4, h5, h6',\n getDepth = getDefaultDepth,\n getValue = getDefaultValue,\n offset = 0,\n scrollHost,\n}: UseScrollSpyOptions = {}): UseScrollSpyReturnValue {\n const [active, setActive] = useState(-1);\n const [initialized, setInitialized] = useState(false);\n const [data, setData] = useState<UseScrollSpyHeadingData[]>([]);\n const headingsRef = useRef<UseScrollSpyHeadingData[]>([]);\n\n const handleScroll = useEffectEvent(() => {\n setActive(\n getActiveElement(\n headingsRef.current.map((d) => d.getNode().getBoundingClientRect()),\n offset\n )\n );\n });\n\n const initialize = () => {\n const headings = getHeadingsData(\n Array.from(document.querySelectorAll(selector)),\n getDepth,\n getValue\n );\n headingsRef.current = headings;\n setInitialized(true);\n setData(headings);\n setActive(\n getActiveElement(\n headings.map((d) => d.getNode().getBoundingClientRect()),\n offset\n )\n );\n };\n\n useEffect(() => {\n initialize();\n const _scrollHost = resolveScrollHost(scrollHost);\n _scrollHost.addEventListener('scroll', handleScroll);\n return () => _scrollHost.removeEventListener('scroll', handleScroll);\n }, [scrollHost, selector, offset]);\n\n return {\n reinitialize: initialize,\n active,\n initialized,\n data,\n };\n}\n\nexport namespace useScrollSpy {\n export type Options = UseScrollSpyOptions;\n export type ReturnValue = UseScrollSpyReturnValue;\n}\n"],"mappings":";;;;AAGA,SAAS,gBACP,UACA,UACA,UAC2B;CAC3B,MAAM,SAAoC,CAAC;CAE3C,KAAK,IAAI,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK,GAAG;EAC3C,MAAM,UAAU,SAAS;EACzB,OAAO,KAAK;GACV,OAAO,SAAS,OAAO;GACvB,OAAO,SAAS,OAAO;GACvB,IAAI,QAAQ,MAAMA,kBAAAA,SAAS;GAC3B,eAAgB,QAAQ,KAAK,SAAS,eAAe,QAAQ,EAAE,IAAK;EACtE,CAAC;CACH;CAEA,OAAO;AACT;AAEA,SAAS,iBAAiB,OAAkB,SAAiB,GAAG;CAC9D,IAAI,MAAM,WAAW,GACnB,OAAO;CAiBT,OAdgB,MAAM,QACnB,KAAK,MAAM,UAAU;EACpB,IAAI,KAAK,IAAI,IAAI,WAAW,MAAM,IAAI,KAAK,IAAI,KAAK,IAAI,MAAM,GAC5D,OAAO;EAGT,OAAO;GACL;GACA,UAAU,KAAK;EACjB;CACF,GACA;EAAE,OAAO;EAAG,UAAU,MAAM,EAAE,CAAC;CAAE,CAGtB,CAAC,CAAC;AACjB;AAEA,SAAS,gBAAgB,SAAsB;CAC7C,OAAO,OAAO,QAAQ,QAAQ,EAAE;AAClC;AAEA,SAAS,gBAAgB,SAAsB;CAC7C,OAAO,QAAQ,eAAe;AAChC;AAEA,SAAS,kBACP,YACsB;CACtB,IAAI,CAAC,YACH,OAAO;CAGT,IAAI,aAAa,YACf,OAAO,WAAW,WAAW;CAG/B,OAAO;AACT;AA+CA,SAAgB,aAAa,EAC3B,WAAW,0BACX,WAAW,iBACX,WAAW,iBACX,SAAS,GACT,eACuB,CAAC,GAA4B;CACpD,MAAM,CAAC,QAAQ,cAAA,GAAaC,MAAAA,SAAAA,CAAS,EAAE;CACvC,MAAM,CAAC,aAAa,mBAAA,GAAkBA,MAAAA,SAAAA,CAAS,KAAK;CACpD,MAAM,CAAC,MAAM,YAAA,GAAWA,MAAAA,SAAAA,CAAoC,CAAC,CAAC;CAC9D,MAAM,eAAA,GAAcC,MAAAA,OAAAA,CAAkC,CAAC,CAAC;CAExD,MAAM,gBAAA,GAAeC,MAAAA,eAAAA,OAAqB;EACxC,UACE,iBACE,YAAY,QAAQ,KAAK,MAAM,EAAE,QAAQ,CAAC,CAAC,sBAAsB,CAAC,GAClE,MACF,CACF;CACF,CAAC;CAED,MAAM,mBAAmB;EACvB,MAAM,WAAW,gBACf,MAAM,KAAK,SAAS,iBAAiB,QAAQ,CAAC,GAC9C,UACA,QACF;EACA,YAAY,UAAU;EACtB,eAAe,IAAI;EACnB,QAAQ,QAAQ;EAChB,UACE,iBACE,SAAS,KAAK,MAAM,EAAE,QAAQ,CAAC,CAAC,sBAAsB,CAAC,GACvD,MACF,CACF;CACF;CAEA,CAAA,GAAA,MAAA,UAAA,OAAgB;EACd,WAAW;EACX,MAAM,cAAc,kBAAkB,UAAU;EAChD,YAAY,iBAAiB,UAAU,YAAY;EACnD,aAAa,YAAY,oBAAoB,UAAU,YAAY;CACrE,GAAG;EAAC;EAAY;EAAU;CAAM,CAAC;CAEjC,OAAO;EACL,cAAc;EACd;EACA;EACA;CACF;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"use-scroller.cjs","names":[],"sources":["../../src/use-scroller/use-scroller.ts"],"sourcesContent":["import { RefCallback, useCallback, useEffect, useRef, useState } from 'react';\n\nexport interface UseScrollerOptions {\n /** Amount of pixels to scroll when calling scroll functions, `200` by default */\n scrollAmount?: number;\n\n /** Determines whether content can be scrolled by dragging with mouse, `true` by default */\n draggable?: boolean;\n\n /** Called when scroll state changes (canScrollStart or canScrollEnd) */\n onScrollStateChange?: (state: UseScrollerScrollState) => void;\n}\n\nexport interface UseScrollerScrollState {\n /** Whether content can be scrolled towards the start (left in LTR, right in RTL) */\n canScrollStart: boolean;\n\n /** Whether content can be scrolled towards the end (right in LTR, left in RTL) */\n canScrollEnd: boolean;\n}\n\nexport interface UseScrollerReturnValue<T extends HTMLElement = HTMLDivElement> {\n /** Ref callback to attach to the scrollable container element */\n ref: RefCallback<T | null>;\n\n /** Whether content can be scrolled towards the start */\n canScrollStart: boolean;\n\n /** Whether content can be scrolled towards the end */\n canScrollEnd: boolean;\n\n /** Scrolls towards the start direction */\n scrollStart: () => void;\n\n /** Scrolls towards the end direction */\n scrollEnd: () => void;\n\n /** `true` if the user is currently dragging the content */\n isDragging: boolean;\n\n /** Props to spread on the scrollable container for drag functionality */\n dragHandlers: {\n onMouseDown: (e: React.MouseEvent) => void;\n onMouseMove: (e: React.MouseEvent) => void;\n onMouseUp: () => void;\n onMouseLeave: () => void;\n };\n}\n\nexport function useScroller<T extends HTMLElement = HTMLDivElement>(\n options: UseScrollerOptions = {}\n): UseScrollerReturnValue<T> {\n const { scrollAmount = 200, draggable = true, onScrollStateChange } = options;\n\n const containerRef = useRef<T | null>(null);\n\n const [canScrollStart, setCanScrollStart] = useState(false);\n const [canScrollEnd, setCanScrollEnd] = useState(false);\n const [isDragging, setIsDragging] = useState(false);\n\n const isDraggingRef = useRef(false);\n const hasDraggedRef = useRef(false);\n const startX = useRef(0);\n const scrollLeftStart = useRef(0);\n\n const onScrollStateChangeRef = useRef(onScrollStateChange);\n onScrollStateChangeRef.current = onScrollStateChange;\n\n const updateScrollState = useCallback(() => {\n const container = containerRef.current;\n if (container) {\n const { scrollLeft, scrollWidth, clientWidth } = container;\n const isRtl = getComputedStyle(container).direction === 'rtl';\n\n let newCanScrollStart: boolean;\n let newCanScrollEnd: boolean;\n\n if (isRtl) {\n newCanScrollStart = scrollLeft < -1;\n newCanScrollEnd = scrollLeft > -(scrollWidth - clientWidth) + 1;\n } else {\n newCanScrollStart = scrollLeft > 1;\n newCanScrollEnd = scrollLeft < scrollWidth - clientWidth - 1;\n }\n\n setCanScrollStart(newCanScrollStart);\n setCanScrollEnd(newCanScrollEnd);\n\n onScrollStateChangeRef.current?.({\n canScrollStart: newCanScrollStart,\n canScrollEnd: newCanScrollEnd,\n });\n }\n }, []);\n\n useEffect(() => {\n updateScrollState();\n const container = containerRef.current;\n if (container) {\n container.addEventListener('scroll', updateScrollState);\n const resizeObserver = new ResizeObserver(updateScrollState);\n resizeObserver.observe(container);\n return () => {\n container.removeEventListener('scroll', updateScrollState);\n resizeObserver.disconnect();\n };\n }\n return undefined;\n }, [updateScrollState]);\n\n const scroll = useCallback(\n (direction: 'start' | 'end') => {\n const container = containerRef.current;\n if (container) {\n const isRtl = getComputedStyle(container).direction === 'rtl';\n const amount = scrollAmount;\n const scrollBy = direction === 'end' ? amount : -amount;\n const adjustedScrollBy = isRtl ? -scrollBy : scrollBy;\n\n container.scrollBy({\n left: adjustedScrollBy,\n behavior: 'smooth',\n });\n }\n },\n [scrollAmount]\n );\n\n const scrollStart = useCallback(() => scroll('start'), [scroll]);\n const scrollEnd = useCallback(() => scroll('end'), [scroll]);\n\n const handleMouseDown = useCallback(\n (event: React.MouseEvent) => {\n if (!draggable) {\n return;\n }\n const container = containerRef.current;\n if (container) {\n isDraggingRef.current = true;\n hasDraggedRef.current = false;\n setIsDragging(true);\n startX.current = event.pageX - container.offsetLeft;\n scrollLeftStart.current = container.scrollLeft;\n container.style.cursor = 'grabbing';\n container.style.userSelect = 'none';\n }\n },\n [draggable]\n );\n\n const handleMouseMove = useCallback((event: React.MouseEvent) => {\n if (!isDraggingRef.current) {\n return;\n }\n event.preventDefault();\n const container = containerRef.current;\n if (container) {\n const x = event.pageX - container.offsetLeft;\n const walk = x - startX.current;\n if (Math.abs(walk) > 5) {\n hasDraggedRef.current = true;\n }\n container.scrollLeft = scrollLeftStart.current - walk;\n }\n }, []);\n\n const handleMouseUp = useCallback(() => {\n const wasDragged = hasDraggedRef.current;\n isDraggingRef.current = false;\n hasDraggedRef.current = false;\n setIsDragging(false);\n const container = containerRef.current;\n if (container) {\n container.style.cursor = '';\n container.style.userSelect = '';\n\n if (wasDragged) {\n const suppressClick = (event: MouseEvent) => {\n event.stopPropagation();\n event.preventDefault();\n container.removeEventListener('click', suppressClick, true);\n };\n container.addEventListener('click', suppressClick, true);\n }\n }\n }, []);\n\n const handleMouseLeave = useCallback(() => {\n if (isDraggingRef.current) {\n handleMouseUp();\n }\n }, [handleMouseUp]);\n\n const assignRef: RefCallback<T | null> = useCallback(\n (node) => {\n containerRef.current = node;\n if (node) {\n updateScrollState();\n }\n },\n [updateScrollState]\n );\n\n return {\n ref: assignRef,\n canScrollStart,\n canScrollEnd,\n scrollStart,\n scrollEnd,\n isDragging,\n dragHandlers: {\n onMouseDown: handleMouseDown,\n onMouseMove: handleMouseMove,\n onMouseUp: handleMouseUp,\n onMouseLeave: handleMouseLeave,\n },\n };\n}\n\nexport namespace useScroller {\n export type Options = UseScrollerOptions;\n export type ReturnValue<T extends HTMLElement = HTMLDivElement> = UseScrollerReturnValue<T>;\n export type ScrollState = UseScrollerScrollState;\n}\n"],"mappings":";;;AAiDA,SAAgB,YACd,UAA8B,CAAC,GACJ;CAC3B,MAAM,EAAE,eAAe,KAAK,YAAY,MAAM,wBAAwB;CAEtE,MAAM,gBAAA,GAAA,MAAA,OAAA,CAAgC,IAAI;CAE1C,MAAM,CAAC,gBAAgB,sBAAA,GAAA,MAAA,SAAA,CAA8B,KAAK;CAC1D,MAAM,CAAC,cAAc,oBAAA,GAAA,MAAA,SAAA,CAA4B,KAAK;CACtD,MAAM,CAAC,YAAY,kBAAA,GAAA,MAAA,SAAA,CAA0B,KAAK;CAElD,MAAM,iBAAA,GAAA,MAAA,OAAA,CAAuB,KAAK;CAClC,MAAM,iBAAA,GAAA,MAAA,OAAA,CAAuB,KAAK;CAClC,MAAM,UAAA,GAAA,MAAA,OAAA,CAAgB,CAAC;CACvB,MAAM,mBAAA,GAAA,MAAA,OAAA,CAAyB,CAAC;CAEhC,MAAM,0BAAA,GAAA,MAAA,OAAA,CAAgC,mBAAmB;CACzD,uBAAuB,UAAU;CAEjC,MAAM,qBAAA,GAAA,MAAA,YAAA,OAAsC;EAC1C,MAAM,YAAY,aAAa;EAC/B,IAAI,WAAW;GACb,MAAM,EAAE,YAAY,aAAa,gBAAgB;GACjD,MAAM,QAAQ,iBAAiB,SAAS,CAAC,CAAC,cAAc;GAExD,IAAI;GACJ,IAAI;GAEJ,IAAI,OAAO;IACT,oBAAoB,aAAa;IACjC,kBAAkB,aAAa,EAAE,cAAc,eAAe;GAChE,OAAO;IACL,oBAAoB,aAAa;IACjC,kBAAkB,aAAa,cAAc,cAAc;GAC7D;GAEA,kBAAkB,iBAAiB;GACnC,gBAAgB,eAAe;GAE/B,uBAAuB,UAAU;IAC/B,gBAAgB;IAChB,cAAc;GAChB,CAAC;EACH;CACF,GAAG,CAAC,CAAC;CAEL,CAAA,GAAA,MAAA,UAAA,OAAgB;EACd,kBAAkB;EAClB,MAAM,YAAY,aAAa;EAC/B,IAAI,WAAW;GACb,UAAU,iBAAiB,UAAU,iBAAiB;GACtD,MAAM,iBAAiB,IAAI,eAAe,iBAAiB;GAC3D,eAAe,QAAQ,SAAS;GAChC,aAAa;IACX,UAAU,oBAAoB,UAAU,iBAAiB;IACzD,eAAe,WAAW;GAC5B;EACF;CAEF,GAAG,CAAC,iBAAiB,CAAC;CAEtB,MAAM,UAAA,GAAA,MAAA,YAAA,EACH,cAA+B;EAC9B,MAAM,YAAY,aAAa;EAC/B,IAAI,WAAW;GACb,MAAM,QAAQ,iBAAiB,SAAS,CAAC,CAAC,cAAc;GACxD,MAAM,SAAS;GACf,MAAM,WAAW,cAAc,QAAQ,SAAS,CAAC;GACjD,MAAM,mBAAmB,QAAQ,CAAC,WAAW;GAE7C,UAAU,SAAS;IACjB,MAAM;IACN,UAAU;GACZ,CAAC;EACH;CACF,GACA,CAAC,YAAY,CACf;CAEA,MAAM,eAAA,GAAA,MAAA,YAAA,OAAgC,OAAO,OAAO,GAAG,CAAC,MAAM,CAAC;CAC/D,MAAM,aAAA,GAAA,MAAA,YAAA,OAA8B,OAAO,KAAK,GAAG,CAAC,MAAM,CAAC;CAE3D,MAAM,mBAAA,GAAA,MAAA,YAAA,EACH,UAA4B;EAC3B,IAAI,CAAC,WACH;EAEF,MAAM,YAAY,aAAa;EAC/B,IAAI,WAAW;GACb,cAAc,UAAU;GACxB,cAAc,UAAU;GACxB,cAAc,IAAI;GAClB,OAAO,UAAU,MAAM,QAAQ,UAAU;GACzC,gBAAgB,UAAU,UAAU;GACpC,UAAU,MAAM,SAAS;GACzB,UAAU,MAAM,aAAa;EAC/B;CACF,GACA,CAAC,SAAS,CACZ;CAEA,MAAM,mBAAA,GAAA,MAAA,YAAA,EAA+B,UAA4B;EAC/D,IAAI,CAAC,cAAc,SACjB;EAEF,MAAM,eAAe;EACrB,MAAM,YAAY,aAAa;EAC/B,IAAI,WAAW;GAEb,MAAM,OADI,MAAM,QAAQ,UAAU,aACjB,OAAO;GACxB,IAAI,KAAK,IAAI,IAAI,IAAI,GACnB,cAAc,UAAU;GAE1B,UAAU,aAAa,gBAAgB,UAAU;EACnD;CACF,GAAG,CAAC,CAAC;CAEL,MAAM,iBAAA,GAAA,MAAA,YAAA,OAAkC;EACtC,MAAM,aAAa,cAAc;EACjC,cAAc,UAAU;EACxB,cAAc,UAAU;EACxB,cAAc,KAAK;EACnB,MAAM,YAAY,aAAa;EAC/B,IAAI,WAAW;GACb,UAAU,MAAM,SAAS;GACzB,UAAU,MAAM,aAAa;GAE7B,IAAI,YAAY;IACd,MAAM,iBAAiB,UAAsB;KAC3C,MAAM,gBAAgB;KACtB,MAAM,eAAe;KACrB,UAAU,oBAAoB,SAAS,eAAe,IAAI;IAC5D;IACA,UAAU,iBAAiB,SAAS,eAAe,IAAI;GACzD;EACF;CACF,GAAG,CAAC,CAAC;CAEL,MAAM,oBAAA,GAAA,MAAA,YAAA,OAAqC;EACzC,IAAI,cAAc,SAChB,cAAc;CAElB,GAAG,CAAC,aAAa,CAAC;CAYlB,OAAO;EACL,MAAA,GAAA,MAAA,YAAA,EAVC,SAAS;GACR,aAAa,UAAU;GACvB,IAAI,MACF,kBAAkB;EAEtB,GACA,CAAC,iBAAiB,CAIL;EACb;EACA;EACA;EACA;EACA;EACA,cAAc;GACZ,aAAa;GACb,aAAa;GACb,WAAW;GACX,cAAc;EAChB;CACF;AACF"}
1
+ {"version":3,"file":"use-scroller.cjs","names":["useRef","useState","useCallback"],"sources":["../../src/use-scroller/use-scroller.ts"],"sourcesContent":["import { RefCallback, useCallback, useEffect, useRef, useState } from 'react';\n\nexport interface UseScrollerOptions {\n /** Amount of pixels to scroll when calling scroll functions, `200` by default */\n scrollAmount?: number;\n\n /** Determines whether content can be scrolled by dragging with mouse, `true` by default */\n draggable?: boolean;\n\n /** Called when scroll state changes (canScrollStart or canScrollEnd) */\n onScrollStateChange?: (state: UseScrollerScrollState) => void;\n}\n\nexport interface UseScrollerScrollState {\n /** Whether content can be scrolled towards the start (left in LTR, right in RTL) */\n canScrollStart: boolean;\n\n /** Whether content can be scrolled towards the end (right in LTR, left in RTL) */\n canScrollEnd: boolean;\n}\n\nexport interface UseScrollerReturnValue<T extends HTMLElement = HTMLDivElement> {\n /** Ref callback to attach to the scrollable container element */\n ref: RefCallback<T | null>;\n\n /** Whether content can be scrolled towards the start */\n canScrollStart: boolean;\n\n /** Whether content can be scrolled towards the end */\n canScrollEnd: boolean;\n\n /** Scrolls towards the start direction */\n scrollStart: () => void;\n\n /** Scrolls towards the end direction */\n scrollEnd: () => void;\n\n /** `true` if the user is currently dragging the content */\n isDragging: boolean;\n\n /** Props to spread on the scrollable container for drag functionality */\n dragHandlers: {\n onMouseDown: (e: React.MouseEvent) => void;\n onMouseMove: (e: React.MouseEvent) => void;\n onMouseUp: () => void;\n onMouseLeave: () => void;\n };\n}\n\nexport function useScroller<T extends HTMLElement = HTMLDivElement>(\n options: UseScrollerOptions = {}\n): UseScrollerReturnValue<T> {\n const { scrollAmount = 200, draggable = true, onScrollStateChange } = options;\n\n const containerRef = useRef<T | null>(null);\n\n const [canScrollStart, setCanScrollStart] = useState(false);\n const [canScrollEnd, setCanScrollEnd] = useState(false);\n const [isDragging, setIsDragging] = useState(false);\n\n const isDraggingRef = useRef(false);\n const hasDraggedRef = useRef(false);\n const startX = useRef(0);\n const scrollLeftStart = useRef(0);\n\n const onScrollStateChangeRef = useRef(onScrollStateChange);\n onScrollStateChangeRef.current = onScrollStateChange;\n\n const updateScrollState = useCallback(() => {\n const container = containerRef.current;\n if (container) {\n const { scrollLeft, scrollWidth, clientWidth } = container;\n const isRtl = getComputedStyle(container).direction === 'rtl';\n\n let newCanScrollStart: boolean;\n let newCanScrollEnd: boolean;\n\n if (isRtl) {\n newCanScrollStart = scrollLeft < -1;\n newCanScrollEnd = scrollLeft > -(scrollWidth - clientWidth) + 1;\n } else {\n newCanScrollStart = scrollLeft > 1;\n newCanScrollEnd = scrollLeft < scrollWidth - clientWidth - 1;\n }\n\n setCanScrollStart(newCanScrollStart);\n setCanScrollEnd(newCanScrollEnd);\n\n onScrollStateChangeRef.current?.({\n canScrollStart: newCanScrollStart,\n canScrollEnd: newCanScrollEnd,\n });\n }\n }, []);\n\n useEffect(() => {\n updateScrollState();\n const container = containerRef.current;\n if (container) {\n container.addEventListener('scroll', updateScrollState);\n const resizeObserver = new ResizeObserver(updateScrollState);\n resizeObserver.observe(container);\n return () => {\n container.removeEventListener('scroll', updateScrollState);\n resizeObserver.disconnect();\n };\n }\n return undefined;\n }, [updateScrollState]);\n\n const scroll = useCallback(\n (direction: 'start' | 'end') => {\n const container = containerRef.current;\n if (container) {\n const isRtl = getComputedStyle(container).direction === 'rtl';\n const amount = scrollAmount;\n const scrollBy = direction === 'end' ? amount : -amount;\n const adjustedScrollBy = isRtl ? -scrollBy : scrollBy;\n\n container.scrollBy({\n left: adjustedScrollBy,\n behavior: 'smooth',\n });\n }\n },\n [scrollAmount]\n );\n\n const scrollStart = useCallback(() => scroll('start'), [scroll]);\n const scrollEnd = useCallback(() => scroll('end'), [scroll]);\n\n const handleMouseDown = useCallback(\n (event: React.MouseEvent) => {\n if (!draggable) {\n return;\n }\n const container = containerRef.current;\n if (container) {\n isDraggingRef.current = true;\n hasDraggedRef.current = false;\n setIsDragging(true);\n startX.current = event.pageX - container.offsetLeft;\n scrollLeftStart.current = container.scrollLeft;\n container.style.cursor = 'grabbing';\n container.style.userSelect = 'none';\n }\n },\n [draggable]\n );\n\n const handleMouseMove = useCallback((event: React.MouseEvent) => {\n if (!isDraggingRef.current) {\n return;\n }\n event.preventDefault();\n const container = containerRef.current;\n if (container) {\n const x = event.pageX - container.offsetLeft;\n const walk = x - startX.current;\n if (Math.abs(walk) > 5) {\n hasDraggedRef.current = true;\n }\n container.scrollLeft = scrollLeftStart.current - walk;\n }\n }, []);\n\n const handleMouseUp = useCallback(() => {\n const wasDragged = hasDraggedRef.current;\n isDraggingRef.current = false;\n hasDraggedRef.current = false;\n setIsDragging(false);\n const container = containerRef.current;\n if (container) {\n container.style.cursor = '';\n container.style.userSelect = '';\n\n if (wasDragged) {\n const suppressClick = (event: MouseEvent) => {\n event.stopPropagation();\n event.preventDefault();\n container.removeEventListener('click', suppressClick, true);\n };\n container.addEventListener('click', suppressClick, true);\n }\n }\n }, []);\n\n const handleMouseLeave = useCallback(() => {\n if (isDraggingRef.current) {\n handleMouseUp();\n }\n }, [handleMouseUp]);\n\n const assignRef: RefCallback<T | null> = useCallback(\n (node) => {\n containerRef.current = node;\n if (node) {\n updateScrollState();\n }\n },\n [updateScrollState]\n );\n\n return {\n ref: assignRef,\n canScrollStart,\n canScrollEnd,\n scrollStart,\n scrollEnd,\n isDragging,\n dragHandlers: {\n onMouseDown: handleMouseDown,\n onMouseMove: handleMouseMove,\n onMouseUp: handleMouseUp,\n onMouseLeave: handleMouseLeave,\n },\n };\n}\n\nexport namespace useScroller {\n export type Options = UseScrollerOptions;\n export type ReturnValue<T extends HTMLElement = HTMLDivElement> = UseScrollerReturnValue<T>;\n export type ScrollState = UseScrollerScrollState;\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"use-selection.cjs","names":[],"sources":["../../src/use-selection/use-selection.ts"],"sourcesContent":["import { useCallback, useState } from 'react';\nimport { useDidUpdate } from '../use-did-update/use-did-update';\n\nexport interface UseSelectionInput<T> {\n /** The array of items to select from */\n data: T[];\n\n /** The initial selection, empty array by default */\n defaultSelection?: T[];\n\n /** If true, selection is reset when data changes */\n resetSelectionOnDataChange?: boolean;\n}\n\nexport interface UseSelectionHandlers<T> {\n /** Add an item to the selection */\n select: (selected: T) => void;\n\n /** Remove an item from the selection */\n deselect: (deselected: T) => void;\n\n /** Toggle an item's selection state */\n toggle: (toggled: T) => void;\n\n /** Returns true if all items from the `data` are selected */\n isAllSelected: () => boolean;\n\n /** Returns true if at least one item from the `data` is selected */\n isSomeSelected: () => boolean;\n\n /** Set the selection to a specific array of items */\n setSelection: (selection: T[]) => void;\n\n /** Clear all selections */\n resetSelection: () => void;\n}\n\nexport type UseSelectionReturnValue<T> = readonly [T[], UseSelectionHandlers<T>];\n\nexport function useSelection<T>(input: UseSelectionInput<T>): UseSelectionReturnValue<T> {\n const [selectionSet, setSelectionSet] = useState<Set<T>>(new Set(input.defaultSelection || []));\n\n useDidUpdate(() => {\n if (input.resetSelectionOnDataChange) {\n setSelectionSet(new Set());\n }\n }, [input.data, input.resetSelectionOnDataChange]);\n\n const select = useCallback((selected: T) => {\n setSelectionSet((state) => {\n if (!state.has(selected)) {\n const newSet = new Set(state);\n newSet.add(selected);\n return newSet;\n }\n return state;\n });\n }, []);\n\n const deselect = useCallback((deselected: T) => {\n setSelectionSet((state) => {\n if (state.has(deselected)) {\n const newSet = new Set(state);\n newSet.delete(deselected);\n return newSet;\n }\n return state;\n });\n }, []);\n\n const toggle = useCallback((toggled: T) => {\n setSelectionSet((state) => {\n const newSet = new Set(state);\n if (state.has(toggled)) {\n newSet.delete(toggled);\n } else {\n newSet.add(toggled);\n }\n return newSet;\n });\n }, []);\n\n const resetSelection = useCallback(() => {\n setSelectionSet(new Set());\n }, []);\n\n const setSelection = useCallback((selection: T[]) => {\n setSelectionSet(new Set(selection));\n }, []);\n\n const isAllSelected = useCallback(() => {\n if (input.data.length === 0) {\n return false;\n }\n return input.data.every((item) => selectionSet.has(item));\n }, [selectionSet, input.data]);\n\n const isSomeSelected = useCallback(() => {\n return input.data.some((item) => selectionSet.has(item));\n }, [selectionSet, input.data]);\n\n return [\n Array.from(selectionSet),\n {\n select,\n deselect,\n toggle,\n isAllSelected,\n isSomeSelected,\n setSelection,\n resetSelection,\n },\n ];\n}\n\nexport namespace useSelection {\n export type Input<T> = UseSelectionInput<T>;\n export type Handlers<T> = UseSelectionHandlers<T>;\n export type ReturnValue<T> = UseSelectionReturnValue<T>;\n}\n"],"mappings":";;;;AAuCA,SAAgB,aAAgB,OAAyD;CACvF,MAAM,CAAC,cAAc,oBAAA,GAAA,MAAA,SAAA,CAAoC,IAAI,IAAI,MAAM,oBAAoB,CAAC,CAAC,CAAC;CAE9F,uBAAA,mBAAmB;EACjB,IAAI,MAAM,4BACR,gCAAgB,IAAI,IAAI,CAAC;CAE7B,GAAG,CAAC,MAAM,MAAM,MAAM,0BAA0B,CAAC;CAEjD,MAAM,UAAA,GAAA,MAAA,YAAA,EAAsB,aAAgB;EAC1C,iBAAiB,UAAU;GACzB,IAAI,CAAC,MAAM,IAAI,QAAQ,GAAG;IACxB,MAAM,SAAS,IAAI,IAAI,KAAK;IAC5B,OAAO,IAAI,QAAQ;IACnB,OAAO;GACT;GACA,OAAO;EACT,CAAC;CACH,GAAG,CAAC,CAAC;CAEL,MAAM,YAAA,GAAA,MAAA,YAAA,EAAwB,eAAkB;EAC9C,iBAAiB,UAAU;GACzB,IAAI,MAAM,IAAI,UAAU,GAAG;IACzB,MAAM,SAAS,IAAI,IAAI,KAAK;IAC5B,OAAO,OAAO,UAAU;IACxB,OAAO;GACT;GACA,OAAO;EACT,CAAC;CACH,GAAG,CAAC,CAAC;CAEL,MAAM,UAAA,GAAA,MAAA,YAAA,EAAsB,YAAe;EACzC,iBAAiB,UAAU;GACzB,MAAM,SAAS,IAAI,IAAI,KAAK;GAC5B,IAAI,MAAM,IAAI,OAAO,GACnB,OAAO,OAAO,OAAO;QAErB,OAAO,IAAI,OAAO;GAEpB,OAAO;EACT,CAAC;CACH,GAAG,CAAC,CAAC;CAEL,MAAM,kBAAA,GAAA,MAAA,YAAA,OAAmC;EACvC,gCAAgB,IAAI,IAAI,CAAC;CAC3B,GAAG,CAAC,CAAC;CAEL,MAAM,gBAAA,GAAA,MAAA,YAAA,EAA4B,cAAmB;EACnD,gBAAgB,IAAI,IAAI,SAAS,CAAC;CACpC,GAAG,CAAC,CAAC;CAEL,MAAM,iBAAA,GAAA,MAAA,YAAA,OAAkC;EACtC,IAAI,MAAM,KAAK,WAAW,GACxB,OAAO;EAET,OAAO,MAAM,KAAK,OAAO,SAAS,aAAa,IAAI,IAAI,CAAC;CAC1D,GAAG,CAAC,cAAc,MAAM,IAAI,CAAC;CAE7B,MAAM,kBAAA,GAAA,MAAA,YAAA,OAAmC;EACvC,OAAO,MAAM,KAAK,MAAM,SAAS,aAAa,IAAI,IAAI,CAAC;CACzD,GAAG,CAAC,cAAc,MAAM,IAAI,CAAC;CAE7B,OAAO,CACL,MAAM,KAAK,YAAY,GACvB;EACE;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CACF;AACF"}
1
+ {"version":3,"file":"use-selection.cjs","names":["useState","useCallback"],"sources":["../../src/use-selection/use-selection.ts"],"sourcesContent":["import { useCallback, useState } from 'react';\nimport { useDidUpdate } from '../use-did-update/use-did-update';\n\nexport interface UseSelectionInput<T> {\n /** The array of items to select from */\n data: T[];\n\n /** The initial selection, empty array by default */\n defaultSelection?: T[];\n\n /** If true, selection is reset when data changes */\n resetSelectionOnDataChange?: boolean;\n}\n\nexport interface UseSelectionHandlers<T> {\n /** Add an item to the selection */\n select: (selected: T) => void;\n\n /** Remove an item from the selection */\n deselect: (deselected: T) => void;\n\n /** Toggle an item's selection state */\n toggle: (toggled: T) => void;\n\n /** Returns true if all items from the `data` are selected */\n isAllSelected: () => boolean;\n\n /** Returns true if at least one item from the `data` is selected */\n isSomeSelected: () => boolean;\n\n /** Set the selection to a specific array of items */\n setSelection: (selection: T[]) => void;\n\n /** Clear all selections */\n resetSelection: () => void;\n}\n\nexport type UseSelectionReturnValue<T> = readonly [T[], UseSelectionHandlers<T>];\n\nexport function useSelection<T>(input: UseSelectionInput<T>): UseSelectionReturnValue<T> {\n const [selectionSet, setSelectionSet] = useState<Set<T>>(new Set(input.defaultSelection || []));\n\n useDidUpdate(() => {\n if (input.resetSelectionOnDataChange) {\n setSelectionSet(new Set());\n }\n }, [input.data, input.resetSelectionOnDataChange]);\n\n const select = useCallback((selected: T) => {\n setSelectionSet((state) => {\n if (!state.has(selected)) {\n const newSet = new Set(state);\n newSet.add(selected);\n return newSet;\n }\n return state;\n });\n }, []);\n\n const deselect = useCallback((deselected: T) => {\n setSelectionSet((state) => {\n if (state.has(deselected)) {\n const newSet = new Set(state);\n newSet.delete(deselected);\n return newSet;\n }\n return state;\n });\n }, []);\n\n const toggle = useCallback((toggled: T) => {\n setSelectionSet((state) => {\n const newSet = new Set(state);\n if (state.has(toggled)) {\n newSet.delete(toggled);\n } else {\n newSet.add(toggled);\n }\n return newSet;\n });\n }, []);\n\n const resetSelection = useCallback(() => {\n setSelectionSet(new Set());\n }, []);\n\n const setSelection = useCallback((selection: T[]) => {\n setSelectionSet(new Set(selection));\n }, []);\n\n const isAllSelected = useCallback(() => {\n if (input.data.length === 0) {\n return false;\n }\n return input.data.every((item) => selectionSet.has(item));\n }, [selectionSet, input.data]);\n\n const isSomeSelected = useCallback(() => {\n return input.data.some((item) => selectionSet.has(item));\n }, [selectionSet, input.data]);\n\n return [\n Array.from(selectionSet),\n {\n select,\n deselect,\n toggle,\n isAllSelected,\n isSomeSelected,\n setSelection,\n resetSelection,\n },\n ];\n}\n\nexport namespace useSelection {\n export type Input<T> = UseSelectionInput<T>;\n export type Handlers<T> = UseSelectionHandlers<T>;\n export type ReturnValue<T> = UseSelectionReturnValue<T>;\n}\n"],"mappings":";;;;AAuCA,SAAgB,aAAgB,OAAyD;CACvF,MAAM,CAAC,cAAc,oBAAA,GAAmBA,MAAAA,SAAAA,CAAiB,IAAI,IAAI,MAAM,oBAAoB,CAAC,CAAC,CAAC;CAE9F,uBAAA,mBAAmB;EACjB,IAAI,MAAM,4BACR,gCAAgB,IAAI,IAAI,CAAC;CAE7B,GAAG,CAAC,MAAM,MAAM,MAAM,0BAA0B,CAAC;CAEjD,MAAM,UAAA,GAASC,MAAAA,YAAAA,EAAa,aAAgB;EAC1C,iBAAiB,UAAU;GACzB,IAAI,CAAC,MAAM,IAAI,QAAQ,GAAG;IACxB,MAAM,SAAS,IAAI,IAAI,KAAK;IAC5B,OAAO,IAAI,QAAQ;IACnB,OAAO;GACT;GACA,OAAO;EACT,CAAC;CACH,GAAG,CAAC,CAAC;CAEL,MAAM,YAAA,GAAWA,MAAAA,YAAAA,EAAa,eAAkB;EAC9C,iBAAiB,UAAU;GACzB,IAAI,MAAM,IAAI,UAAU,GAAG;IACzB,MAAM,SAAS,IAAI,IAAI,KAAK;IAC5B,OAAO,OAAO,UAAU;IACxB,OAAO;GACT;GACA,OAAO;EACT,CAAC;CACH,GAAG,CAAC,CAAC;CAEL,MAAM,UAAA,GAASA,MAAAA,YAAAA,EAAa,YAAe;EACzC,iBAAiB,UAAU;GACzB,MAAM,SAAS,IAAI,IAAI,KAAK;GAC5B,IAAI,MAAM,IAAI,OAAO,GACnB,OAAO,OAAO,OAAO;QAErB,OAAO,IAAI,OAAO;GAEpB,OAAO;EACT,CAAC;CACH,GAAG,CAAC,CAAC;CAEL,MAAM,kBAAA,GAAiBA,MAAAA,YAAAA,OAAkB;EACvC,gCAAgB,IAAI,IAAI,CAAC;CAC3B,GAAG,CAAC,CAAC;CAEL,MAAM,gBAAA,GAAeA,MAAAA,YAAAA,EAAa,cAAmB;EACnD,gBAAgB,IAAI,IAAI,SAAS,CAAC;CACpC,GAAG,CAAC,CAAC;CAEL,MAAM,iBAAA,GAAgBA,MAAAA,YAAAA,OAAkB;EACtC,IAAI,MAAM,KAAK,WAAW,GACxB,OAAO;EAET,OAAO,MAAM,KAAK,OAAO,SAAS,aAAa,IAAI,IAAI,CAAC;CAC1D,GAAG,CAAC,cAAc,MAAM,IAAI,CAAC;CAE7B,MAAM,kBAAA,GAAiBA,MAAAA,YAAAA,OAAkB;EACvC,OAAO,MAAM,KAAK,MAAM,SAAS,aAAa,IAAI,IAAI,CAAC;CACzD,GAAG,CAAC,cAAc,MAAM,IAAI,CAAC;CAE7B,OAAO,CACL,MAAM,KAAK,YAAY,GACvB;EACE;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CACF;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"use-set.cjs","names":[],"sources":["../../src/use-set/use-set.ts"],"sourcesContent":["import { useRef, useState } from 'react';\n\nexport function readonlySetLikeToSet<T>(input: ReadonlySetLike<T>): Set<T> {\n if (input instanceof Set) {\n return input;\n }\n const result = new Set<T>();\n const iterator = input.keys();\n let next = iterator.next();\n while (!next.done) {\n result.add(next.value);\n next = iterator.next();\n }\n return result;\n}\n\nexport function useSet<T>(values?: T[]): Set<T> {\n const [set, setSet] = useState(() => new Set(values));\n const setRef = useRef(set);\n setRef.current = set;\n\n set.add = (...args) => {\n const res = Set.prototype.add.apply(setRef.current, args);\n setSet(new Set(setRef.current));\n return res;\n };\n\n set.clear = (...args) => {\n Set.prototype.clear.apply(setRef.current, args);\n setSet(new Set(setRef.current));\n };\n\n set.delete = (...args) => {\n const res = Set.prototype.delete.apply(setRef.current, args);\n setSet(new Set(setRef.current));\n return res;\n };\n\n set.union = <U>(other: ReadonlySetLike<U>): Set<T | U> => {\n const result = new Set<T | U>(setRef.current as Set<T>);\n readonlySetLikeToSet(other).forEach((item) => result.add(item));\n return result;\n };\n\n set.intersection = <U>(other: ReadonlySetLike<U>): Set<T & U> => {\n const result = new Set<T & U>();\n const otherSet = readonlySetLikeToSet(other);\n setRef.current.forEach((item) => {\n if (otherSet.has(item as any)) {\n result.add(item as T & U);\n }\n });\n return result;\n };\n\n set.difference = <U>(other: ReadonlySetLike<U>): Set<T> => {\n const result = new Set<T>();\n const otherSet = readonlySetLikeToSet(other);\n setRef.current.forEach((item) => {\n if (!otherSet.has(item as any)) {\n result.add(item);\n }\n });\n return result;\n };\n\n set.symmetricDifference = <U>(other: ReadonlySetLike<U>): Set<T | U> => {\n const result = new Set<T | U>();\n const otherSet = readonlySetLikeToSet(other);\n\n setRef.current.forEach((item) => {\n if (!otherSet.has(item as any)) {\n result.add(item);\n }\n });\n\n otherSet.forEach((item) => {\n if (!setRef.current.has(item as any)) {\n result.add(item);\n }\n });\n\n return result;\n };\n\n return set;\n}\n"],"mappings":";;;AAEA,SAAgB,qBAAwB,OAAmC;CACzE,IAAI,iBAAiB,KACnB,OAAO;CAET,MAAM,yBAAS,IAAI,IAAO;CAC1B,MAAM,WAAW,MAAM,KAAK;CAC5B,IAAI,OAAO,SAAS,KAAK;CACzB,OAAO,CAAC,KAAK,MAAM;EACjB,OAAO,IAAI,KAAK,KAAK;EACrB,OAAO,SAAS,KAAK;CACvB;CACA,OAAO;AACT;AAEA,SAAgB,OAAU,QAAsB;CAC9C,MAAM,CAAC,KAAK,WAAA,GAAA,MAAA,SAAA,OAAyB,IAAI,IAAI,MAAM,CAAC;CACpD,MAAM,UAAA,GAAA,MAAA,OAAA,CAAgB,GAAG;CACzB,OAAO,UAAU;CAEjB,IAAI,OAAO,GAAG,SAAS;EACrB,MAAM,MAAM,IAAI,UAAU,IAAI,MAAM,OAAO,SAAS,IAAI;EACxD,OAAO,IAAI,IAAI,OAAO,OAAO,CAAC;EAC9B,OAAO;CACT;CAEA,IAAI,SAAS,GAAG,SAAS;EACvB,IAAI,UAAU,MAAM,MAAM,OAAO,SAAS,IAAI;EAC9C,OAAO,IAAI,IAAI,OAAO,OAAO,CAAC;CAChC;CAEA,IAAI,UAAU,GAAG,SAAS;EACxB,MAAM,MAAM,IAAI,UAAU,OAAO,MAAM,OAAO,SAAS,IAAI;EAC3D,OAAO,IAAI,IAAI,OAAO,OAAO,CAAC;EAC9B,OAAO;CACT;CAEA,IAAI,SAAY,UAA0C;EACxD,MAAM,SAAS,IAAI,IAAW,OAAO,OAAiB;EACtD,qBAAqB,KAAK,CAAC,CAAC,SAAS,SAAS,OAAO,IAAI,IAAI,CAAC;EAC9D,OAAO;CACT;CAEA,IAAI,gBAAmB,UAA0C;EAC/D,MAAM,yBAAS,IAAI,IAAW;EAC9B,MAAM,WAAW,qBAAqB,KAAK;EAC3C,OAAO,QAAQ,SAAS,SAAS;GAC/B,IAAI,SAAS,IAAI,IAAW,GAC1B,OAAO,IAAI,IAAa;EAE5B,CAAC;EACD,OAAO;CACT;CAEA,IAAI,cAAiB,UAAsC;EACzD,MAAM,yBAAS,IAAI,IAAO;EAC1B,MAAM,WAAW,qBAAqB,KAAK;EAC3C,OAAO,QAAQ,SAAS,SAAS;GAC/B,IAAI,CAAC,SAAS,IAAI,IAAW,GAC3B,OAAO,IAAI,IAAI;EAEnB,CAAC;EACD,OAAO;CACT;CAEA,IAAI,uBAA0B,UAA0C;EACtE,MAAM,yBAAS,IAAI,IAAW;EAC9B,MAAM,WAAW,qBAAqB,KAAK;EAE3C,OAAO,QAAQ,SAAS,SAAS;GAC/B,IAAI,CAAC,SAAS,IAAI,IAAW,GAC3B,OAAO,IAAI,IAAI;EAEnB,CAAC;EAED,SAAS,SAAS,SAAS;GACzB,IAAI,CAAC,OAAO,QAAQ,IAAI,IAAW,GACjC,OAAO,IAAI,IAAI;EAEnB,CAAC;EAED,OAAO;CACT;CAEA,OAAO;AACT"}
1
+ {"version":3,"file":"use-set.cjs","names":["useState","useRef"],"sources":["../../src/use-set/use-set.ts"],"sourcesContent":["import { useRef, useState } from 'react';\n\nexport function readonlySetLikeToSet<T>(input: ReadonlySetLike<T>): Set<T> {\n if (input instanceof Set) {\n return input;\n }\n const result = new Set<T>();\n const iterator = input.keys();\n let next = iterator.next();\n while (!next.done) {\n result.add(next.value);\n next = iterator.next();\n }\n return result;\n}\n\nexport function useSet<T>(values?: T[]): Set<T> {\n const [set, setSet] = useState(() => new Set(values));\n const setRef = useRef(set);\n setRef.current = set;\n\n set.add = (...args) => {\n const res = Set.prototype.add.apply(setRef.current, args);\n setSet(new Set(setRef.current));\n return res;\n };\n\n set.clear = (...args) => {\n Set.prototype.clear.apply(setRef.current, args);\n setSet(new Set(setRef.current));\n };\n\n set.delete = (...args) => {\n const res = Set.prototype.delete.apply(setRef.current, args);\n setSet(new Set(setRef.current));\n return res;\n };\n\n set.union = <U>(other: ReadonlySetLike<U>): Set<T | U> => {\n const result = new Set<T | U>(setRef.current as Set<T>);\n readonlySetLikeToSet(other).forEach((item) => result.add(item));\n return result;\n };\n\n set.intersection = <U>(other: ReadonlySetLike<U>): Set<T & U> => {\n const result = new Set<T & U>();\n const otherSet = readonlySetLikeToSet(other);\n setRef.current.forEach((item) => {\n if (otherSet.has(item as any)) {\n result.add(item as T & U);\n }\n });\n return result;\n };\n\n set.difference = <U>(other: ReadonlySetLike<U>): Set<T> => {\n const result = new Set<T>();\n const otherSet = readonlySetLikeToSet(other);\n setRef.current.forEach((item) => {\n if (!otherSet.has(item as any)) {\n result.add(item);\n }\n });\n return result;\n };\n\n set.symmetricDifference = <U>(other: ReadonlySetLike<U>): Set<T | U> => {\n const result = new Set<T | U>();\n const otherSet = readonlySetLikeToSet(other);\n\n setRef.current.forEach((item) => {\n if (!otherSet.has(item as any)) {\n result.add(item);\n }\n });\n\n otherSet.forEach((item) => {\n if (!setRef.current.has(item as any)) {\n result.add(item);\n }\n });\n\n return result;\n };\n\n return set;\n}\n"],"mappings":";;;AAEA,SAAgB,qBAAwB,OAAmC;CACzE,IAAI,iBAAiB,KACnB,OAAO;CAET,MAAM,yBAAS,IAAI,IAAO;CAC1B,MAAM,WAAW,MAAM,KAAK;CAC5B,IAAI,OAAO,SAAS,KAAK;CACzB,OAAO,CAAC,KAAK,MAAM;EACjB,OAAO,IAAI,KAAK,KAAK;EACrB,OAAO,SAAS,KAAK;CACvB;CACA,OAAO;AACT;AAEA,SAAgB,OAAU,QAAsB;CAC9C,MAAM,CAAC,KAAK,WAAA,GAAUA,MAAAA,SAAAA,OAAe,IAAI,IAAI,MAAM,CAAC;CACpD,MAAM,UAAA,GAASC,MAAAA,OAAAA,CAAO,GAAG;CACzB,OAAO,UAAU;CAEjB,IAAI,OAAO,GAAG,SAAS;EACrB,MAAM,MAAM,IAAI,UAAU,IAAI,MAAM,OAAO,SAAS,IAAI;EACxD,OAAO,IAAI,IAAI,OAAO,OAAO,CAAC;EAC9B,OAAO;CACT;CAEA,IAAI,SAAS,GAAG,SAAS;EACvB,IAAI,UAAU,MAAM,MAAM,OAAO,SAAS,IAAI;EAC9C,OAAO,IAAI,IAAI,OAAO,OAAO,CAAC;CAChC;CAEA,IAAI,UAAU,GAAG,SAAS;EACxB,MAAM,MAAM,IAAI,UAAU,OAAO,MAAM,OAAO,SAAS,IAAI;EAC3D,OAAO,IAAI,IAAI,OAAO,OAAO,CAAC;EAC9B,OAAO;CACT;CAEA,IAAI,SAAY,UAA0C;EACxD,MAAM,SAAS,IAAI,IAAW,OAAO,OAAiB;EACtD,qBAAqB,KAAK,CAAC,CAAC,SAAS,SAAS,OAAO,IAAI,IAAI,CAAC;EAC9D,OAAO;CACT;CAEA,IAAI,gBAAmB,UAA0C;EAC/D,MAAM,yBAAS,IAAI,IAAW;EAC9B,MAAM,WAAW,qBAAqB,KAAK;EAC3C,OAAO,QAAQ,SAAS,SAAS;GAC/B,IAAI,SAAS,IAAI,IAAW,GAC1B,OAAO,IAAI,IAAa;EAE5B,CAAC;EACD,OAAO;CACT;CAEA,IAAI,cAAiB,UAAsC;EACzD,MAAM,yBAAS,IAAI,IAAO;EAC1B,MAAM,WAAW,qBAAqB,KAAK;EAC3C,OAAO,QAAQ,SAAS,SAAS;GAC/B,IAAI,CAAC,SAAS,IAAI,IAAW,GAC3B,OAAO,IAAI,IAAI;EAEnB,CAAC;EACD,OAAO;CACT;CAEA,IAAI,uBAA0B,UAA0C;EACtE,MAAM,yBAAS,IAAI,IAAW;EAC9B,MAAM,WAAW,qBAAqB,KAAK;EAE3C,OAAO,QAAQ,SAAS,SAAS;GAC/B,IAAI,CAAC,SAAS,IAAI,IAAW,GAC3B,OAAO,IAAI,IAAI;EAEnB,CAAC;EAED,SAAS,SAAS,SAAS;GACzB,IAAI,CAAC,OAAO,QAAQ,IAAI,IAAW,GACjC,OAAO,IAAI,IAAI;EAEnB,CAAC;EAED,OAAO;CACT;CAEA,OAAO;AACT"}
@@ -1 +1 @@
1
- {"version":3,"file":"use-set-state.cjs","names":[],"sources":["../../src/use-set-state/use-set-state.ts"],"sourcesContent":["import { useCallback, useState } from 'react';\n\nexport type UseSetStateCallback<T> = (\n state: Partial<T> | ((currentState: T) => Partial<T>)\n) => void;\n\nexport type UseSetStateReturnValue<T> = [T, UseSetStateCallback<T>];\n\nexport function useSetState<T extends Record<string, any>>(\n initialState: T\n): UseSetStateReturnValue<T> {\n const [state, setState] = useState(initialState);\n\n const _setState: UseSetStateCallback<T> = useCallback(\n (statePartial) =>\n setState((current) => ({\n ...current,\n ...(typeof statePartial === 'function' ? statePartial(current) : statePartial),\n })),\n []\n );\n\n return [state, _setState];\n}\n\nexport namespace useSetState {\n export type Callback<T> = UseSetStateCallback<T>;\n export type ReturnValue<T> = UseSetStateReturnValue<T>;\n}\n"],"mappings":";;;AAQA,SAAgB,YACd,cAC2B;CAC3B,MAAM,CAAC,OAAO,aAAA,GAAA,MAAA,SAAA,CAAqB,YAAY;CAW/C,OAAO,CAAC,QAAA,GAAA,MAAA,YAAA,EARL,iBACC,UAAU,aAAa;EACrB,GAAG;EACH,GAAI,OAAO,iBAAiB,aAAa,aAAa,OAAO,IAAI;CACnE,EAAE,GACJ,CAAC,CAGoB,CAAC;AAC1B"}
1
+ {"version":3,"file":"use-set-state.cjs","names":["useState","useCallback"],"sources":["../../src/use-set-state/use-set-state.ts"],"sourcesContent":["import { useCallback, useState } from 'react';\n\nexport type UseSetStateCallback<T> = (\n state: Partial<T> | ((currentState: T) => Partial<T>)\n) => void;\n\nexport type UseSetStateReturnValue<T> = [T, UseSetStateCallback<T>];\n\nexport function useSetState<T extends Record<string, any>>(\n initialState: T\n): UseSetStateReturnValue<T> {\n const [state, setState] = useState(initialState);\n\n const _setState: UseSetStateCallback<T> = useCallback(\n (statePartial) =>\n setState((current) => ({\n ...current,\n ...(typeof statePartial === 'function' ? statePartial(current) : statePartial),\n })),\n []\n );\n\n return [state, _setState];\n}\n\nexport namespace useSetState {\n export type Callback<T> = UseSetStateCallback<T>;\n export type ReturnValue<T> = UseSetStateReturnValue<T>;\n}\n"],"mappings":";;;AAQA,SAAgB,YACd,cAC2B;CAC3B,MAAM,CAAC,OAAO,aAAA,GAAYA,MAAAA,SAAAA,CAAS,YAAY;CAW/C,OAAO,CAAC,QAAA,GATkCC,MAAAA,YAAAA,EACvC,iBACC,UAAU,aAAa;EACrB,GAAG;EACH,GAAI,OAAO,iBAAiB,aAAa,aAAa,OAAO,IAAI;CACnE,EAAE,GACJ,CAAC,CAGoB,CAAC;AAC1B"}
@@ -1 +1 @@
1
- {"version":3,"file":"use-shallow-effect.cjs","names":["shallowEqual"],"sources":["../../src/use-shallow-effect/use-shallow-effect.ts"],"sourcesContent":["import { useEffect, useRef } from 'react';\nimport { shallowEqual } from '../utils/shallow-equal/shallow-equal';\n\nfunction shallowCompare(prevValue?: React.DependencyList | null, currValue?: React.DependencyList) {\n if (!prevValue || !currValue) {\n return false;\n }\n\n if (prevValue === currValue) {\n return true;\n }\n\n if (prevValue.length !== currValue.length) {\n return false;\n }\n\n for (let i = 0; i < prevValue.length; i += 1) {\n if (!shallowEqual(prevValue[i], currValue[i])) {\n return false;\n }\n }\n\n return true;\n}\n\nfunction useShallowCompare(dependencies?: React.DependencyList) {\n const ref = useRef<React.DependencyList | null | undefined>([]);\n const updateRef = useRef<number>(0);\n\n if (!shallowCompare(ref.current, dependencies)) {\n ref.current = dependencies;\n updateRef.current += 1;\n }\n\n return [updateRef.current];\n}\n\nexport function useShallowEffect(cb: () => void, dependencies?: React.DependencyList): void {\n useEffect(cb, useShallowCompare(dependencies));\n}\n"],"mappings":";;;;AAGA,SAAS,eAAe,WAAyC,WAAkC;CACjG,IAAI,CAAC,aAAa,CAAC,WACjB,OAAO;CAGT,IAAI,cAAc,WAChB,OAAO;CAGT,IAAI,UAAU,WAAW,UAAU,QACjC,OAAO;CAGT,KAAK,IAAI,IAAI,GAAG,IAAI,UAAU,QAAQ,KAAK,GACzC,IAAI,CAACA,sBAAAA,aAAa,UAAU,IAAI,UAAU,EAAE,GAC1C,OAAO;CAIX,OAAO;AACT;AAEA,SAAS,kBAAkB,cAAqC;CAC9D,MAAM,OAAA,GAAA,MAAA,OAAA,CAAsD,CAAC,CAAC;CAC9D,MAAM,aAAA,GAAA,MAAA,OAAA,CAA2B,CAAC;CAElC,IAAI,CAAC,eAAe,IAAI,SAAS,YAAY,GAAG;EAC9C,IAAI,UAAU;EACd,UAAU,WAAW;CACvB;CAEA,OAAO,CAAC,UAAU,OAAO;AAC3B;AAEA,SAAgB,iBAAiB,IAAgB,cAA2C;CAC1F,CAAA,GAAA,MAAA,UAAA,CAAU,IAAI,kBAAkB,YAAY,CAAC;AAC/C"}
1
+ {"version":3,"file":"use-shallow-effect.cjs","names":["shallowEqual","useRef"],"sources":["../../src/use-shallow-effect/use-shallow-effect.ts"],"sourcesContent":["import { useEffect, useRef } from 'react';\nimport { shallowEqual } from '../utils/shallow-equal/shallow-equal';\n\nfunction shallowCompare(prevValue?: React.DependencyList | null, currValue?: React.DependencyList) {\n if (!prevValue || !currValue) {\n return false;\n }\n\n if (prevValue === currValue) {\n return true;\n }\n\n if (prevValue.length !== currValue.length) {\n return false;\n }\n\n for (let i = 0; i < prevValue.length; i += 1) {\n if (!shallowEqual(prevValue[i], currValue[i])) {\n return false;\n }\n }\n\n return true;\n}\n\nfunction useShallowCompare(dependencies?: React.DependencyList) {\n const ref = useRef<React.DependencyList | null | undefined>([]);\n const updateRef = useRef<number>(0);\n\n if (!shallowCompare(ref.current, dependencies)) {\n ref.current = dependencies;\n updateRef.current += 1;\n }\n\n return [updateRef.current];\n}\n\nexport function useShallowEffect(cb: () => void, dependencies?: React.DependencyList): void {\n useEffect(cb, useShallowCompare(dependencies));\n}\n"],"mappings":";;;;AAGA,SAAS,eAAe,WAAyC,WAAkC;CACjG,IAAI,CAAC,aAAa,CAAC,WACjB,OAAO;CAGT,IAAI,cAAc,WAChB,OAAO;CAGT,IAAI,UAAU,WAAW,UAAU,QACjC,OAAO;CAGT,KAAK,IAAI,IAAI,GAAG,IAAI,UAAU,QAAQ,KAAK,GACzC,IAAI,CAACA,sBAAAA,aAAa,UAAU,IAAI,UAAU,EAAE,GAC1C,OAAO;CAIX,OAAO;AACT;AAEA,SAAS,kBAAkB,cAAqC;CAC9D,MAAM,OAAA,GAAMC,MAAAA,OAAAA,CAAgD,CAAC,CAAC;CAC9D,MAAM,aAAA,GAAYA,MAAAA,OAAAA,CAAe,CAAC;CAElC,IAAI,CAAC,eAAe,IAAI,SAAS,YAAY,GAAG;EAC9C,IAAI,UAAU;EACd,UAAU,WAAW;CACvB;CAEA,OAAO,CAAC,UAAU,OAAO;AAC3B;AAEA,SAAgB,iBAAiB,IAAgB,cAA2C;CAC1F,CAAA,GAAA,MAAA,UAAA,CAAU,IAAI,kBAAkB,YAAY,CAAC;AAC/C"}
@@ -1 +1 @@
1
- {"version":3,"file":"use-splitter.cjs","names":["useUncontrolled"],"sources":["../../src/use-splitter/use-splitter.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-deprecated */\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport { useUncontrolled } from '../use-uncontrolled/use-uncontrolled';\n\n/** Pane size expressed in CSS units. A bare `number` or `%` string is a flexible size (shares\n * the leftover space), `px`/`rem` strings are fixed sizes that keep their pixel size when the\n * container is resized. */\nexport type SplitterPaneSize = number | `${number}%` | `${number}px` | `${number}rem`;\n\n/** Keyboard step expressed in CSS units. A bare `number` or `%` string is a percentage of the\n * container, `px`/`rem` strings are resolved to pixels. */\nexport type SplitterStep = number | `${number}%` | `${number}px` | `${number}rem`;\n\nexport interface UseSplitterPanel {\n /** Initial size, a `number`/`%` is a flexible size, `px`/`rem` is a fixed size. A bare number is treated as a percentage. */\n defaultSize: SplitterPaneSize;\n /** Minimum size in the same units as `defaultSize`, `0` by default */\n min?: SplitterPaneSize;\n /** Maximum size in the same units as `defaultSize`, no limit by default */\n max?: SplitterPaneSize;\n /** Whether this panel can be collapsed, `false` by default */\n collapsible?: boolean;\n /** Size below which the panel snaps to collapsed, defaults to `min` */\n collapseThreshold?: SplitterPaneSize;\n}\n\n/** Panel configuration resolved to numeric units (percent or pixels) passed to redistribute functions */\nexport interface UseSplitterResolvedPanel {\n /** Resolved default size in the same units as redistribute sizes */\n defaultSize: number;\n /** Resolved minimum size */\n min?: number;\n /** Resolved maximum size */\n max?: number;\n /** Whether this panel can be collapsed */\n collapsible?: boolean;\n /** Resolved collapse threshold */\n collapseThreshold?: number;\n}\n\nexport interface UseSplitterRedistributeInput {\n /** Current sizes before applying delta, in resolved units (percent or pixels) */\n sizes: number[];\n /** Resolved panel configurations, in the same units as `sizes` */\n panels: UseSplitterResolvedPanel[];\n /** Index of the handle being dragged */\n handleIndex: number;\n /** Requested size change in resolved units (positive = grow before-panel) */\n delta: number;\n}\n\nexport type UseSplitterRedistributeFn = (input: UseSplitterRedistributeInput) => number[];\n\nexport interface UseSplitterOptions {\n /** Panel configuration array (minimum 2 panels) */\n panels: UseSplitterPanel[];\n /** Layout direction, `'horizontal'` by default */\n orientation?: 'horizontal' | 'vertical';\n /** Controlled sizes, each value keeps the unit it was declared in */\n sizes?: SplitterPaneSize[];\n /** Called during resize with updated sizes, each value keeps its declared unit */\n onSizeChange?: (sizes: SplitterPaneSize[]) => void;\n /** Called when drag starts */\n onResizeStart?: (handleIndex: number) => void;\n /** Called when drag ends */\n onResizeEnd?: (handleIndex: number, sizes: SplitterPaneSize[]) => void;\n /** Called when a panel collapses or expands */\n onCollapseChange?: (panelIndex: number, collapsed: boolean) => void;\n /** How to borrow space from non-adjacent panels when the immediate neighbor is at its min/max.\n * `'nearest'` takes from the nearest panel in the drag direction first.\n * `'equal'` distributes equally among all panels in the drag direction.\n * A function receives sizes, panels, handleIndex and delta, and returns new sizes.\n * When not set, only the two adjacent panels are affected. */\n redistribute?: 'nearest' | 'equal' | UseSplitterRedistributeFn;\n /** Keyboard step size, a `number`/`%` is a percentage, `px`/`rem` is resolved to pixels, `1` by default */\n step?: SplitterStep;\n /** Shift+arrow step size, a `number`/`%` is a percentage, `px`/`rem` is resolved to pixels, `10` by default */\n shiftStep?: SplitterStep;\n /** Text direction for keyboard nav, `'ltr'` by default */\n dir?: 'ltr' | 'rtl';\n /** Restore the two panels adjacent to a handle to their default ratio (preserving their combined size) when the handle is double-clicked, `true` by default */\n resetOnDoubleClick?: boolean;\n /** Enable/disable the hook, `true` by default */\n enabled?: boolean;\n}\n\nexport interface UseSplitterReturnValue<T extends HTMLElement = any> {\n /** Ref callback for the container element */\n ref: React.RefCallback<T | null>;\n /** Current panel sizes, each value keeps the unit it was declared in */\n sizes: SplitterPaneSize[];\n /** Whether sizes are tracked in pixels because any pane size, `min`, `max`, `step`, `shiftStep`\n * or `collapseThreshold` uses a fixed `px`/`rem` unit */\n pixelMode: boolean;\n /** Which panels are currently collapsed */\n collapsed: boolean[];\n /** Index of handle being dragged, or -1 */\n activeHandle: number;\n /** Get props to spread on each resize handle */\n getHandleProps: (input: { index: number }) => {\n ref: React.RefCallback<HTMLElement>;\n role: 'separator';\n 'aria-orientation': 'horizontal' | 'vertical';\n 'aria-valuenow': number;\n 'aria-valuemin': number;\n 'aria-valuemax': number;\n tabIndex: number;\n onKeyDown: React.KeyboardEventHandler;\n onDoubleClick: React.MouseEventHandler;\n 'data-active': boolean | undefined;\n 'data-orientation': 'horizontal' | 'vertical';\n };\n /** Programmatically set sizes, each value keeps its declared unit */\n setSizes: (sizes: SplitterPaneSize[]) => void;\n /** Collapse a panel */\n collapse: (panelIndex: number) => void;\n /** Expand a collapsed panel */\n expand: (panelIndex: number) => void;\n /** Toggle collapse of a panel */\n toggleCollapse: (panelIndex: number) => void;\n /** Reset the two panels adjacent to a handle to their default ratio, preserving\n * their combined size */\n reset: (handleIndex: number) => void;\n}\n\nconst PX_RE = /^(-?[\\d.]+)px$/;\nconst REM_RE = /^(-?[\\d.]+)rem$/;\nconst PERCENT_RE = /^(-?[\\d.]+)%$/;\n\nfunction isFixedSize(size: SplitterPaneSize | undefined): boolean {\n return typeof size === 'string' && (PX_RE.test(size) || REM_RE.test(size));\n}\n\nfunction sizeMagnitude(size: SplitterPaneSize): number {\n return typeof size === 'number' ? size : parseFloat(size);\n}\n\nfunction detectPixelMode(options: UseSplitterOptions): boolean {\n return (\n options.panels.some(\n (panel) =>\n isFixedSize(panel.defaultSize) ||\n isFixedSize(panel.min) ||\n isFixedSize(panel.max) ||\n isFixedSize(panel.collapseThreshold)\n ) ||\n isFixedSize(options.step) ||\n isFixedSize(options.shiftStep) ||\n (options.sizes?.some(isFixedSize) ?? false)\n );\n}\n\nfunction getRootFontSize(): number {\n if (typeof window === 'undefined') {\n return 16;\n }\n const fontSize = parseFloat(getComputedStyle(document.documentElement).fontSize);\n return Number.isFinite(fontSize) && fontSize > 0 ? fontSize : 16;\n}\n\nfunction resolveSize(\n size: SplitterPaneSize,\n pixelMode: boolean,\n containerPx: number,\n rootFontSize: number\n): number {\n if (!pixelMode) {\n return sizeMagnitude(size);\n }\n\n if (typeof size === 'number') {\n return (size / 100) * containerPx;\n }\n\n const percent = PERCENT_RE.exec(size);\n if (percent) {\n return (parseFloat(percent[1]) / 100) * containerPx;\n }\n\n const rem = REM_RE.exec(size);\n if (rem) {\n return parseFloat(rem[1]) * rootFontSize;\n }\n\n const px = PX_RE.exec(size);\n if (px) {\n return parseFloat(px[1]);\n }\n\n return 0;\n}\n\n/** Down-scaling factor applied to fixed panes when their combined pixel size overflows the\n * container, so they shrink to fit (matching `resolveWorkingSizes`). Returns `1` when nothing\n * overflows or the layout is not in pixel mode. Encoders divide by this to invert the scaling and\n * persist the original absolute sizes instead of the shrunk-to-fit ones. */\nfunction getFixedScale(\n sizes: SplitterPaneSize[],\n pixelMode: boolean,\n containerPx: number,\n rootFontSize: number\n): number {\n if (!pixelMode) {\n return 1;\n }\n\n let fixedTotal = 0;\n sizes.forEach((size) => {\n if (isFixedSize(size)) {\n fixedTotal += resolveSize(size, true, containerPx, rootFontSize);\n }\n });\n\n return fixedTotal > containerPx && fixedTotal > 0 ? containerPx / fixedTotal : 1;\n}\n\n/** Resolves all sizes to pixels at once. Fixed panes get their absolute pixel size, flexible panes\n * share the leftover space by their weight ratio – matching how the layout is rendered with\n * `flex-grow`, so drag math operates on the same pixel sizes the user sees. */\nfunction resolveWorkingSizes(\n sizes: SplitterPaneSize[],\n pixelMode: boolean,\n containerPx: number,\n rootFontSize: number\n): number[] {\n if (!pixelMode) {\n return sizes.map((size) => sizeMagnitude(size));\n }\n\n let fixedTotal = 0;\n let flexibleWeight = 0;\n sizes.forEach((size) => {\n if (isFixedSize(size)) {\n fixedTotal += resolveSize(size, true, containerPx, rootFontSize);\n } else {\n flexibleWeight += sizeMagnitude(size);\n }\n });\n\n const leftover = Math.max(0, containerPx - fixedTotal);\n const fixedScale = getFixedScale(sizes, pixelMode, containerPx, rootFontSize);\n\n return sizes.map((size) => {\n if (isFixedSize(size)) {\n return resolveSize(size, true, containerPx, rootFontSize) * fixedScale;\n }\n return flexibleWeight > 0 ? (sizeMagnitude(size) / flexibleWeight) * leftover : 0;\n });\n}\n\nfunction encodeSize(\n value: number,\n original: SplitterPaneSize,\n pixelMode: boolean,\n containerPx: number,\n rootFontSize: number,\n fixedScale: number = 1\n): SplitterPaneSize {\n if (!pixelMode) {\n return typeof original === 'string' && PERCENT_RE.test(original) ? `${value}%` : value;\n }\n\n if (typeof original === 'number') {\n return containerPx > 0 ? (value / containerPx) * 100 : original;\n }\n\n if (PERCENT_RE.test(original)) {\n return `${containerPx > 0 ? (value / containerPx) * 100 : parseFloat(original)}%`;\n }\n\n const absolute = fixedScale > 0 ? value / fixedScale : value;\n\n if (REM_RE.test(original)) {\n return `${rootFontSize > 0 ? absolute / rootFontSize : 0}rem`;\n }\n\n return `${absolute}px`;\n}\n\n/** Encodes working pixel sizes back to raw sizes after a resize, keeping the unit each pane was\n * declared in. Panes whose working size did not change keep their original raw value. When fixed\n * panes overflow the container they render down-scaled, so their working sizes are scaled back up to\n * absolute sizes (preserving their declared sizes). If the resize instead hands space to a flexible\n * pane the overflow clears and the layout leaves the down-scaled regime: every pane is then encoded\n * from its current working size – including untouched fixed panes (so they do not jump back to their\n * over-sized value) and untouched flexible panes (so a pane that was squeezed to `0` does not keep a\n * stale weight and steal the freed space on the next render). */\nfunction encodeWorkingSizes(\n nextWorking: number[],\n baseWorking: number[],\n baseRaw: SplitterPaneSize[],\n pixelMode: boolean,\n containerPx: number,\n rootFontSize: number\n): SplitterPaneSize[] {\n const fixedScale = getFixedScale(baseRaw, pixelMode, containerPx, rootFontSize);\n\n let fixedWorkingSum = 0;\n nextWorking.forEach((value, i) => {\n if (isFixedSize(baseRaw[i])) {\n fixedWorkingSum += value;\n }\n });\n const overflowCleared = fixedScale < 1 && fixedWorkingSum < containerPx - 1e-6;\n const encodeScale = overflowCleared ? 1 : fixedScale;\n\n return nextWorking.map((value, i) =>\n overflowCleared || Math.abs(value - baseWorking[i]) > 1e-6\n ? encodeSize(value, baseRaw[i], pixelMode, containerPx, rootFontSize, encodeScale)\n : baseRaw[i]\n );\n}\n\nfunction resolvePanel(\n panel: UseSplitterPanel,\n pixelMode: boolean,\n containerPx: number,\n rootFontSize: number\n): UseSplitterResolvedPanel {\n return {\n defaultSize: resolveSize(panel.defaultSize, pixelMode, containerPx, rootFontSize),\n min: panel.min != null ? resolveSize(panel.min, pixelMode, containerPx, rootFontSize) : 0,\n max:\n panel.max != null\n ? resolveSize(panel.max, pixelMode, containerPx, rootFontSize)\n : pixelMode\n ? containerPx\n : 100,\n collapseThreshold:\n panel.collapseThreshold != null\n ? resolveSize(panel.collapseThreshold, pixelMode, containerPx, rootFontSize)\n : undefined,\n collapsible: panel.collapsible,\n };\n}\n\nfunction resolveStep(\n step: SplitterStep,\n pixelMode: boolean,\n containerPx: number,\n rootFontSize: number\n): number {\n return resolveSize(step, pixelMode, containerPx, rootFontSize);\n}\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.min(Math.max(value, min), max);\n}\n\nfunction getMin(panel: UseSplitterResolvedPanel): number {\n return panel.min ?? 0;\n}\n\nfunction getMax(panel: UseSplitterResolvedPanel): number {\n return panel.max ?? Infinity;\n}\n\nfunction getCollapseThreshold(panel: UseSplitterResolvedPanel): number {\n return panel.collapseThreshold ?? getMin(panel);\n}\n\ninterface SplitterInternalState {\n isDragging: boolean;\n handleIndex: number;\n startPointer: number;\n containerSize: number;\n rootFontSize: number;\n pixelMode: boolean;\n startSizes: number[];\n startRaw: SplitterPaneSize[];\n preCollapseSizes: SplitterPaneSize[];\n}\n\nfunction createInitialInternalState(): SplitterInternalState {\n return {\n isDragging: false,\n handleIndex: -1,\n startPointer: 0,\n containerSize: 0,\n rootFontSize: 16,\n pixelMode: false,\n startSizes: [],\n startRaw: [],\n preCollapseSizes: [],\n };\n}\n\nfunction checkCollapse(\n sizes: number[],\n panels: UseSplitterResolvedPanel[],\n handleIndex: number,\n delta: number\n): number[] | null {\n const beforeIdx = handleIndex;\n const afterIdx = handleIndex + 1;\n const beforePanel = panels[beforeIdx];\n const afterPanel = panels[afterIdx];\n\n const rawBefore = sizes[beforeIdx] + delta;\n const rawAfter = sizes[afterIdx] - delta;\n\n if (\n beforePanel.collapsible &&\n rawBefore < getCollapseThreshold(beforePanel) &&\n rawBefore < sizes[beforeIdx]\n ) {\n const result = [...sizes];\n result[afterIdx] += result[beforeIdx];\n result[beforeIdx] = 0;\n return result;\n }\n\n if (\n afterPanel.collapsible &&\n rawAfter < getCollapseThreshold(afterPanel) &&\n rawAfter < sizes[afterIdx]\n ) {\n const result = [...sizes];\n result[beforeIdx] += result[afterIdx];\n result[afterIdx] = 0;\n return result;\n }\n\n return null;\n}\n\nfunction applyAdjacentOnly(\n sizes: number[],\n panels: UseSplitterResolvedPanel[],\n handleIndex: number,\n delta: number\n): number[] {\n const result = [...sizes];\n const beforeIdx = handleIndex;\n const afterIdx = handleIndex + 1;\n\n const total = result[beforeIdx] + result[afterIdx];\n const effectiveBeforeMax = Math.min(getMax(panels[beforeIdx]), total - getMin(panels[afterIdx]));\n const effectiveBeforeMin = Math.max(getMin(panels[beforeIdx]), total - getMax(panels[afterIdx]));\n const newBefore = clamp(result[beforeIdx] + delta, effectiveBeforeMin, effectiveBeforeMax);\n result[beforeIdx] = newBefore;\n result[afterIdx] = total - newBefore;\n return result;\n}\n\nfunction redistributeNearest(\n sizes: number[],\n panels: UseSplitterResolvedPanel[],\n handleIndex: number,\n delta: number\n): number[] {\n const result = [...sizes];\n\n if (delta > 0) {\n const growIdx = handleIndex;\n const maxGrow = getMax(panels[growIdx]) - result[growIdx];\n const wantedGrow = Math.min(delta, maxGrow);\n\n let taken = 0;\n for (let i = handleIndex + 1; i < result.length && taken < wantedGrow; i += 1) {\n const canGive = result[i] - getMin(panels[i]);\n const take = Math.min(canGive, wantedGrow - taken);\n result[i] -= take;\n taken += take;\n }\n\n result[growIdx] += taken;\n } else if (delta < 0) {\n const growIdx = handleIndex + 1;\n const maxGrow = getMax(panels[growIdx]) - result[growIdx];\n const wantedGrow = Math.min(Math.abs(delta), maxGrow);\n\n let taken = 0;\n for (let i = handleIndex; i >= 0 && taken < wantedGrow; i -= 1) {\n const canGive = result[i] - getMin(panels[i]);\n const take = Math.min(canGive, wantedGrow - taken);\n result[i] -= take;\n taken += take;\n }\n\n result[growIdx] += taken;\n }\n\n return result;\n}\n\nfunction redistributeEqual(\n sizes: number[],\n panels: UseSplitterResolvedPanel[],\n handleIndex: number,\n delta: number\n): number[] {\n const result = [...sizes];\n\n if (delta > 0) {\n const growIdx = handleIndex;\n const maxGrow = getMax(panels[growIdx]) - result[growIdx];\n const wantedGrow = Math.min(delta, maxGrow);\n\n const donors: number[] = [];\n for (let i = handleIndex + 1; i < result.length; i += 1) {\n if (result[i] > getMin(panels[i])) {\n donors.push(i);\n }\n }\n\n let remaining = wantedGrow;\n while (remaining > 0.001 && donors.length > 0) {\n const perDonor = remaining / donors.length;\n const exhausted: number[] = [];\n\n for (let d = 0; d < donors.length; d += 1) {\n const idx = donors[d];\n const canGive = result[idx] - getMin(panels[idx]);\n const take = Math.min(canGive, perDonor);\n result[idx] -= take;\n remaining -= take;\n if (canGive <= perDonor + 0.001) {\n exhausted.push(d);\n }\n }\n\n for (let i = exhausted.length - 1; i >= 0; i -= 1) {\n donors.splice(exhausted[i], 1);\n }\n\n if (exhausted.length === 0) {\n break;\n }\n }\n\n result[growIdx] += wantedGrow - remaining;\n } else if (delta < 0) {\n const growIdx = handleIndex + 1;\n const maxGrow = getMax(panels[growIdx]) - result[growIdx];\n const wantedGrow = Math.min(Math.abs(delta), maxGrow);\n\n const donors: number[] = [];\n for (let i = handleIndex; i >= 0; i -= 1) {\n if (result[i] > getMin(panels[i])) {\n donors.push(i);\n }\n }\n\n let remaining = wantedGrow;\n while (remaining > 0.001 && donors.length > 0) {\n const perDonor = remaining / donors.length;\n const exhausted: number[] = [];\n\n for (let d = 0; d < donors.length; d += 1) {\n const idx = donors[d];\n const canGive = result[idx] - getMin(panels[idx]);\n const take = Math.min(canGive, perDonor);\n result[idx] -= take;\n remaining -= take;\n if (canGive <= perDonor + 0.001) {\n exhausted.push(d);\n }\n }\n\n for (let i = exhausted.length - 1; i >= 0; i -= 1) {\n donors.splice(exhausted[i], 1);\n }\n\n if (exhausted.length === 0) {\n break;\n }\n }\n\n result[growIdx] += wantedGrow - remaining;\n }\n\n return result;\n}\n\nfunction applyConstraints(\n sizes: number[],\n panels: UseSplitterResolvedPanel[],\n handleIndex: number,\n delta: number,\n redistribute?: 'nearest' | 'equal' | UseSplitterRedistributeFn\n): number[] {\n if (typeof redistribute === 'function') {\n return redistribute({ sizes: [...sizes], panels, handleIndex, delta });\n }\n\n if (redistribute === 'nearest' || redistribute === 'equal') {\n const strategy = redistribute === 'nearest' ? redistributeNearest : redistributeEqual;\n const result = strategy(sizes, panels, handleIndex, delta);\n\n const beforeIdx = handleIndex;\n const afterIdx = handleIndex + 1;\n const beforePanel = panels[beforeIdx];\n const afterPanel = panels[afterIdx];\n\n if (\n beforePanel.collapsible &&\n result[beforeIdx] < getCollapseThreshold(beforePanel) &&\n result[beforeIdx] < sizes[beforeIdx]\n ) {\n const freed = result[beforeIdx];\n result[afterIdx] += freed;\n result[beforeIdx] = 0;\n } else if (\n afterPanel.collapsible &&\n result[afterIdx] < getCollapseThreshold(afterPanel) &&\n result[afterIdx] < sizes[afterIdx]\n ) {\n const freed = result[afterIdx];\n result[beforeIdx] += freed;\n result[afterIdx] = 0;\n }\n\n return result;\n }\n\n const collapsed = checkCollapse(sizes, panels, handleIndex, delta);\n if (collapsed) {\n return collapsed;\n }\n\n return applyAdjacentOnly(sizes, panels, handleIndex, delta);\n}\n\nexport function useSplitter<T extends HTMLElement = any>(\n options: UseSplitterOptions\n): UseSplitterReturnValue<T> {\n const {\n panels,\n orientation = 'horizontal',\n sizes: controlledSizes,\n onSizeChange,\n onCollapseChange,\n redistribute,\n step = 1,\n shiftStep = 10,\n dir = 'ltr',\n resetOnDoubleClick = true,\n enabled = true,\n } = options;\n\n const pixelMode = detectPixelMode(options);\n\n const defaultSizes = panels.map((panel) => panel.defaultSize);\n\n const [currentSizes, setCurrentSizes] = useUncontrolled<SplitterPaneSize[]>({\n value: controlledSizes,\n defaultValue: defaultSizes,\n finalValue: defaultSizes,\n onChange: onSizeChange,\n });\n\n const [activeHandle, setActiveHandle] = useState(-1);\n const [containerSize, setContainerSize] = useState(0);\n\n const optionsRef = useRef(options);\n optionsRef.current = options;\n\n const internalStateRef = useRef<SplitterInternalState>(createInitialInternalState());\n const containerRef = useRef<T | null>(null);\n const containerSizeRef = useRef(0);\n const rootFontSizeRef = useRef(16);\n const documentControllerRef = useRef<AbortController | null>(null);\n const frameRef = useRef(0);\n const currentSizesRef = useRef(currentSizes);\n currentSizesRef.current = currentSizes;\n\n const preCollapseSizesRef = useRef<SplitterPaneSize[]>(defaultSizes);\n\n const collapsed = currentSizes.map((size) => sizeMagnitude(size) === 0);\n\n const measureContainer = useCallback(() => {\n const node = containerRef.current;\n if (!node) {\n return 0;\n }\n const rect = node.getBoundingClientRect();\n return (optionsRef.current.orientation ?? 'horizontal') === 'horizontal'\n ? rect.width\n : rect.height;\n }, []);\n\n const updateSizes = useCallback(\n (newSizes: SplitterPaneSize[]) => {\n currentSizesRef.current = newSizes;\n setCurrentSizes(newSizes);\n },\n [setCurrentSizes]\n );\n\n const collapsePanel = useCallback(\n (panelIndex: number) => {\n if (!panels[panelIndex]?.collapsible) {\n return;\n }\n const raw = currentSizesRef.current;\n if (sizeMagnitude(raw[panelIndex]) === 0) {\n return;\n }\n\n const container = pixelMode ? containerSizeRef.current || measureContainer() : 0;\n const rootFontSize = rootFontSizeRef.current;\n const working = resolveWorkingSizes(raw, pixelMode, container, rootFontSize);\n\n preCollapseSizesRef.current = [...raw];\n const freedSize = working[panelIndex];\n working[panelIndex] = 0;\n\n const neighbor = panelIndex === 0 ? 1 : panelIndex - 1;\n working[neighbor] += freedSize;\n\n updateSizes(\n working.map((value, i) => encodeSize(value, raw[i], pixelMode, container, rootFontSize))\n );\n onCollapseChange?.(panelIndex, true);\n },\n [panels, pixelMode, measureContainer, updateSizes, onCollapseChange]\n );\n\n const expandPanel = useCallback(\n (panelIndex: number) => {\n if (!panels[panelIndex]?.collapsible) {\n return;\n }\n const raw = currentSizesRef.current;\n if (sizeMagnitude(raw[panelIndex]) !== 0) {\n return;\n }\n\n const container = pixelMode ? containerSizeRef.current || measureContainer() : 0;\n const rootFontSize = rootFontSizeRef.current;\n const working = resolveWorkingSizes(raw, pixelMode, container, rootFontSize);\n\n const preCollapse = preCollapseSizesRef.current;\n const restoreSource =\n preCollapse[panelIndex] != null && sizeMagnitude(preCollapse[panelIndex]) !== 0\n ? preCollapse[panelIndex]\n : panels[panelIndex].defaultSize;\n const restoreSize = resolveSize(restoreSource, pixelMode, container, rootFontSize);\n\n const neighbor = panelIndex === 0 ? 1 : panelIndex - 1;\n const neighborMin =\n panels[neighbor].min != null\n ? resolveSize(panels[neighbor].min!, pixelMode, container, rootFontSize)\n : 0;\n const available = Math.max(0, working[neighbor] - neighborMin);\n const actualRestore = Math.min(restoreSize, available);\n\n if (actualRestore <= 0) {\n return;\n }\n\n working[panelIndex] = actualRestore;\n working[neighbor] -= actualRestore;\n\n updateSizes(\n working.map((value, i) => encodeSize(value, raw[i], pixelMode, container, rootFontSize))\n );\n onCollapseChange?.(panelIndex, false);\n },\n [panels, pixelMode, measureContainer, updateSizes, onCollapseChange]\n );\n\n const toggleCollapsePanel = useCallback(\n (panelIndex: number) => {\n if (sizeMagnitude(currentSizesRef.current[panelIndex]) === 0) {\n expandPanel(panelIndex);\n } else {\n collapsePanel(panelIndex);\n }\n },\n [collapsePanel, expandPanel]\n );\n\n const emitCollapseTransitions = useCallback(\n (\n prev: SplitterPaneSize[],\n next: number[],\n indices: number[],\n preCollapseSnapshot: SplitterPaneSize[]\n ) => {\n const onChange = optionsRef.current.onCollapseChange;\n for (const idx of indices) {\n const wasCollapsed = sizeMagnitude(prev[idx]) === 0;\n const nowCollapsed = next[idx] === 0;\n if (!wasCollapsed && nowCollapsed) {\n preCollapseSizesRef.current = [...preCollapseSnapshot];\n onChange?.(idx, true);\n } else if (wasCollapsed && !nowCollapsed) {\n onChange?.(idx, false);\n }\n }\n },\n []\n );\n\n const reset = useCallback(\n (handleIndex: number) => {\n const raw = currentSizesRef.current;\n\n const beforeIdx = handleIndex;\n const afterIdx = handleIndex + 1;\n if (beforeIdx < 0 || afterIdx >= raw.length) {\n return;\n }\n\n const container = pixelMode ? containerSizeRef.current || measureContainer() : 0;\n const rootFontSize = rootFontSizeRef.current;\n const working = resolveWorkingSizes(raw, pixelMode, container, rootFontSize);\n const resolvedPanels = optionsRef.current.panels.map((panel) =>\n resolvePanel(panel, pixelMode, container, rootFontSize)\n );\n\n const total = working[beforeIdx] + working[afterIdx];\n const defBefore = resolvedPanels[beforeIdx].defaultSize;\n const defAfter = resolvedPanels[afterIdx].defaultSize;\n const defTotal = defBefore + defAfter;\n const targetBefore = defTotal === 0 ? total / 2 : total * (defBefore / defTotal);\n\n const next = applyAdjacentOnly(\n working,\n resolvedPanels,\n beforeIdx,\n targetBefore - working[beforeIdx]\n );\n emitCollapseTransitions(raw, next, [beforeIdx, afterIdx], raw);\n updateSizes(encodeWorkingSizes(next, working, raw, pixelMode, container, rootFontSize));\n },\n [emitCollapseTransitions, updateSizes, pixelMode, measureContainer]\n );\n\n const containerRefCallback: React.RefCallback<T | null> = useCallback((node) => {\n containerRef.current = node;\n }, []);\n\n useEffect(() => {\n if (!pixelMode || typeof ResizeObserver === 'undefined') {\n return undefined;\n }\n\n const node = containerRef.current;\n if (!node) {\n return undefined;\n }\n\n let frame = 0;\n const update = () => {\n const rect = node.getBoundingClientRect();\n const size =\n (optionsRef.current.orientation ?? 'horizontal') === 'horizontal'\n ? rect.width\n : rect.height;\n rootFontSizeRef.current = getRootFontSize();\n containerSizeRef.current = size;\n setContainerSize((prev) => (prev !== size ? size : prev));\n };\n\n const observer = new ResizeObserver(() => {\n cancelAnimationFrame(frame);\n frame = requestAnimationFrame(update);\n });\n\n observer.observe(node);\n update();\n\n return () => {\n cancelAnimationFrame(frame);\n observer.disconnect();\n };\n }, [pixelMode, orientation]);\n\n const handleRefCallbacks = useRef<Map<number, (node: HTMLElement | null) => void>>(new Map());\n const handleElementControllers = useRef<Map<number, AbortController>>(new Map());\n\n const getHandleRefCallback = useCallback(\n (handleIndex: number): React.RefCallback<HTMLElement> => {\n if (handleRefCallbacks.current.has(handleIndex)) {\n return handleRefCallbacks.current.get(handleIndex)!;\n }\n\n const callback = (node: HTMLElement | null) => {\n const existingController = handleElementControllers.current.get(handleIndex);\n if (existingController) {\n existingController.abort();\n handleElementControllers.current.delete(handleIndex);\n }\n\n if (!node) {\n return;\n }\n\n const elementController = new AbortController();\n handleElementControllers.current.set(handleIndex, elementController);\n\n const onPointerDown = (event: PointerEvent) => {\n if (optionsRef.current.enabled === false) {\n return;\n }\n if (event.button !== 0) {\n return;\n }\n\n const container = containerRef.current;\n if (!container) {\n return;\n }\n\n const opts = optionsRef.current;\n const isHorizontal = (opts.orientation ?? 'horizontal') === 'horizontal';\n const rect = container.getBoundingClientRect();\n const containerSizePx = isHorizontal ? rect.width : rect.height;\n const pointerPos = isHorizontal ? event.clientX : event.clientY;\n const isPixelMode = detectPixelMode(opts);\n const rootFontSize = getRootFontSize();\n\n const s = internalStateRef.current;\n s.isDragging = true;\n s.handleIndex = handleIndex;\n s.startPointer = pointerPos;\n s.containerSize = containerSizePx;\n s.rootFontSize = rootFontSize;\n s.pixelMode = isPixelMode;\n s.startRaw = [...currentSizesRef.current];\n s.startSizes = resolveWorkingSizes(\n s.startRaw,\n isPixelMode,\n containerSizePx,\n rootFontSize\n );\n s.preCollapseSizes = [...preCollapseSizesRef.current];\n\n setActiveHandle(handleIndex);\n document.body.style.userSelect = 'none';\n document.body.style.webkitUserSelect = 'none';\n document.body.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n\n opts.onResizeStart?.(handleIndex);\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', onPointerUp, { signal: sig });\n };\n\n const flushResize = (pointerEvent: PointerEvent) => {\n const s = internalStateRef.current;\n if (!s.containerSize) {\n return;\n }\n const opts = optionsRef.current;\n const isHorizontal = (opts.orientation ?? 'horizontal') === 'horizontal';\n const isRtl = isHorizontal && opts.dir === 'rtl';\n const pointerPos = isHorizontal ? pointerEvent.clientX : pointerEvent.clientY;\n const pixelDelta = (isRtl ? -1 : 1) * (pointerPos - s.startPointer);\n const delta = s.pixelMode ? pixelDelta : (pixelDelta / s.containerSize) * 100;\n\n const resolvedPanels = opts.panels.map((panel) =>\n resolvePanel(panel, s.pixelMode, s.containerSize, s.rootFontSize)\n );\n\n const newSizes = applyConstraints(\n s.startSizes,\n resolvedPanels,\n s.handleIndex,\n delta,\n opts.redistribute\n );\n\n const prevSizes = currentSizesRef.current;\n emitCollapseTransitions(\n prevSizes,\n newSizes,\n [s.handleIndex, s.handleIndex + 1],\n s.startRaw\n );\n\n const encoded = encodeWorkingSizes(\n newSizes,\n s.startSizes,\n s.startRaw,\n s.pixelMode,\n s.containerSize,\n s.rootFontSize\n );\n currentSizesRef.current = encoded;\n setCurrentSizes(encoded);\n };\n\n const onPointerMove = (event: PointerEvent) => {\n const s = internalStateRef.current;\n if (!s.isDragging) {\n return;\n }\n\n cancelAnimationFrame(frameRef.current);\n frameRef.current = requestAnimationFrame(() => {\n flushResize(event);\n });\n };\n\n const onPointerUp = (event: PointerEvent) => {\n const s = internalStateRef.current;\n if (!s.isDragging) {\n return;\n }\n\n cancelAnimationFrame(frameRef.current);\n flushResize(event);\n\n s.isDragging = false;\n const finishedHandle = s.handleIndex;\n s.handleIndex = -1;\n\n setActiveHandle(-1);\n document.body.style.userSelect = '';\n document.body.style.webkitUserSelect = '';\n document.body.style.cursor = '';\n\n documentControllerRef.current?.abort();\n documentControllerRef.current = null;\n\n optionsRef.current.onResizeEnd?.(finishedHandle, [...currentSizesRef.current]);\n };\n\n node.addEventListener('pointerdown', onPointerDown, {\n signal: elementController.signal,\n });\n };\n\n handleRefCallbacks.current.set(handleIndex, callback);\n return callback;\n },\n [setCurrentSizes]\n );\n\n const getHandleProps = useCallback(\n (input: { index: number }) => {\n const { index } = input;\n const orient = orientation;\n const rootFontSize = rootFontSizeRef.current;\n const working = resolveWorkingSizes(currentSizes, pixelMode, containerSize, rootFontSize);\n const resolvedPanels = panels.map((panel) =>\n resolvePanel(panel, pixelMode, containerSize, rootFontSize)\n );\n const beforeSize = working[index] ?? 0;\n const beforePanel = resolvedPanels[index];\n\n return {\n ref: getHandleRefCallback(index),\n role: 'separator' as const,\n 'aria-orientation': orient,\n 'aria-valuenow': Math.round(beforeSize),\n 'aria-valuemin': Math.round(getMin(beforePanel)),\n 'aria-valuemax': Math.round(getMax(beforePanel)),\n tabIndex: 0,\n onKeyDown: (event: React.KeyboardEvent) => {\n if (!enabled) {\n return;\n }\n\n const isHorizontal = orient === 'horizontal';\n const isRtl = dir === 'rtl';\n\n const container = pixelMode ? containerSizeRef.current || measureContainer() : 0;\n const liveRootFontSize = rootFontSizeRef.current;\n const liveWorking = resolveWorkingSizes(\n currentSizes,\n pixelMode,\n container,\n liveRootFontSize\n );\n const livePanels = panels.map((panel) =>\n resolvePanel(panel, pixelMode, container, liveRootFontSize)\n );\n const liveBeforePanel = livePanels[index];\n const liveAfterPanel = livePanels[index + 1];\n\n let delta = 0;\n const currentStep = resolveStep(\n event.shiftKey ? shiftStep : step,\n pixelMode,\n container,\n liveRootFontSize\n );\n\n switch (event.key) {\n case 'ArrowLeft': {\n if (!isHorizontal) {\n return;\n }\n delta = isRtl ? currentStep : -currentStep;\n break;\n }\n case 'ArrowRight': {\n if (!isHorizontal) {\n return;\n }\n delta = isRtl ? -currentStep : currentStep;\n break;\n }\n case 'ArrowUp': {\n if (isHorizontal) {\n return;\n }\n delta = -currentStep;\n break;\n }\n case 'ArrowDown': {\n if (isHorizontal) {\n return;\n }\n delta = currentStep;\n break;\n }\n case 'Home': {\n delta = -(liveWorking[index] - getMin(liveBeforePanel));\n break;\n }\n case 'End': {\n delta = getMax(liveBeforePanel) - liveWorking[index];\n break;\n }\n case 'Enter': {\n const beforeCollapsible = liveBeforePanel?.collapsible;\n const afterCollapsible = liveAfterPanel?.collapsible;\n\n if (beforeCollapsible && liveWorking[index] <= liveWorking[index + 1]) {\n toggleCollapsePanel(index);\n event.preventDefault();\n return;\n }\n if (afterCollapsible) {\n toggleCollapsePanel(index + 1);\n event.preventDefault();\n return;\n }\n if (beforeCollapsible) {\n toggleCollapsePanel(index);\n event.preventDefault();\n return;\n }\n return;\n }\n default:\n return;\n }\n\n event.preventDefault();\n\n if (delta !== 0) {\n const newSizes = applyConstraints(liveWorking, livePanels, index, delta, redistribute);\n emitCollapseTransitions(currentSizes, newSizes, [index, index + 1], currentSizes);\n updateSizes(\n encodeWorkingSizes(\n newSizes,\n liveWorking,\n currentSizes,\n pixelMode,\n container,\n liveRootFontSize\n )\n );\n }\n },\n onDoubleClick: () => {\n if (!enabled || !resetOnDoubleClick) {\n return;\n }\n reset(index);\n },\n 'data-active': activeHandle === index || undefined,\n 'data-orientation': orient,\n };\n },\n [\n orientation,\n currentSizes,\n panels,\n pixelMode,\n containerSize,\n enabled,\n dir,\n step,\n shiftStep,\n resetOnDoubleClick,\n activeHandle,\n redistribute,\n measureContainer,\n getHandleRefCallback,\n toggleCollapsePanel,\n updateSizes,\n emitCollapseTransitions,\n reset,\n ]\n );\n\n useEffect(\n () => () => {\n documentControllerRef.current?.abort();\n documentControllerRef.current = null;\n handleElementControllers.current.forEach((controller) => controller.abort());\n handleElementControllers.current.clear();\n cancelAnimationFrame(frameRef.current);\n\n if (internalStateRef.current.isDragging) {\n internalStateRef.current.isDragging = false;\n document.body.style.userSelect = '';\n document.body.style.webkitUserSelect = '';\n document.body.style.cursor = '';\n }\n },\n []\n );\n\n return {\n ref: containerRefCallback,\n sizes: currentSizes,\n pixelMode,\n collapsed,\n activeHandle,\n getHandleProps,\n setSizes: updateSizes,\n collapse: collapsePanel,\n expand: expandPanel,\n toggleCollapse: toggleCollapsePanel,\n reset,\n };\n}\n\nexport namespace useSplitter {\n export type Panel = UseSplitterPanel;\n export type Options = UseSplitterOptions;\n export type RedistributeInput = UseSplitterRedistributeInput;\n export type RedistributeFn = UseSplitterRedistributeFn;\n export type ResolvedPanel = UseSplitterResolvedPanel;\n export type ReturnValue<T extends HTMLElement = any> = UseSplitterReturnValue<T>;\n export type PaneSize = SplitterPaneSize;\n export type Step = SplitterStep;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"use-splitter.cjs","names":["useUncontrolled","useState","useRef","useCallback"],"sources":["../../src/use-splitter/use-splitter.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-deprecated */\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport { useUncontrolled } from '../use-uncontrolled/use-uncontrolled';\n\n/** Pane size expressed in CSS units. A bare `number` or `%` string is a flexible size (shares\n * the leftover space), `px`/`rem` strings are fixed sizes that keep their pixel size when the\n * container is resized. */\nexport type SplitterPaneSize = number | `${number}%` | `${number}px` | `${number}rem`;\n\n/** Keyboard step expressed in CSS units. A bare `number` or `%` string is a percentage of the\n * container, `px`/`rem` strings are resolved to pixels. */\nexport type SplitterStep = number | `${number}%` | `${number}px` | `${number}rem`;\n\nexport interface UseSplitterPanel {\n /** Initial size, a `number`/`%` is a flexible size, `px`/`rem` is a fixed size. A bare number is treated as a percentage. */\n defaultSize: SplitterPaneSize;\n /** Minimum size in the same units as `defaultSize`, `0` by default */\n min?: SplitterPaneSize;\n /** Maximum size in the same units as `defaultSize`, no limit by default */\n max?: SplitterPaneSize;\n /** Whether this panel can be collapsed, `false` by default */\n collapsible?: boolean;\n /** Size below which the panel snaps to collapsed, defaults to `min` */\n collapseThreshold?: SplitterPaneSize;\n}\n\n/** Panel configuration resolved to numeric units (percent or pixels) passed to redistribute functions */\nexport interface UseSplitterResolvedPanel {\n /** Resolved default size in the same units as redistribute sizes */\n defaultSize: number;\n /** Resolved minimum size */\n min?: number;\n /** Resolved maximum size */\n max?: number;\n /** Whether this panel can be collapsed */\n collapsible?: boolean;\n /** Resolved collapse threshold */\n collapseThreshold?: number;\n}\n\nexport interface UseSplitterRedistributeInput {\n /** Current sizes before applying delta, in resolved units (percent or pixels) */\n sizes: number[];\n /** Resolved panel configurations, in the same units as `sizes` */\n panels: UseSplitterResolvedPanel[];\n /** Index of the handle being dragged */\n handleIndex: number;\n /** Requested size change in resolved units (positive = grow before-panel) */\n delta: number;\n}\n\nexport type UseSplitterRedistributeFn = (input: UseSplitterRedistributeInput) => number[];\n\nexport interface UseSplitterOptions {\n /** Panel configuration array (minimum 2 panels) */\n panels: UseSplitterPanel[];\n /** Layout direction, `'horizontal'` by default */\n orientation?: 'horizontal' | 'vertical';\n /** Controlled sizes, each value keeps the unit it was declared in */\n sizes?: SplitterPaneSize[];\n /** Called during resize with updated sizes, each value keeps its declared unit */\n onSizeChange?: (sizes: SplitterPaneSize[]) => void;\n /** Called when drag starts */\n onResizeStart?: (handleIndex: number) => void;\n /** Called when drag ends */\n onResizeEnd?: (handleIndex: number, sizes: SplitterPaneSize[]) => void;\n /** Called when a panel collapses or expands */\n onCollapseChange?: (panelIndex: number, collapsed: boolean) => void;\n /** How to borrow space from non-adjacent panels when the immediate neighbor is at its min/max.\n * `'nearest'` takes from the nearest panel in the drag direction first.\n * `'equal'` distributes equally among all panels in the drag direction.\n * A function receives sizes, panels, handleIndex and delta, and returns new sizes.\n * When not set, only the two adjacent panels are affected. */\n redistribute?: 'nearest' | 'equal' | UseSplitterRedistributeFn;\n /** Keyboard step size, a `number`/`%` is a percentage, `px`/`rem` is resolved to pixels, `1` by default */\n step?: SplitterStep;\n /** Shift+arrow step size, a `number`/`%` is a percentage, `px`/`rem` is resolved to pixels, `10` by default */\n shiftStep?: SplitterStep;\n /** Text direction for keyboard nav, `'ltr'` by default */\n dir?: 'ltr' | 'rtl';\n /** Restore the two panels adjacent to a handle to their default ratio (preserving their combined size) when the handle is double-clicked, `true` by default */\n resetOnDoubleClick?: boolean;\n /** Enable/disable the hook, `true` by default */\n enabled?: boolean;\n}\n\nexport interface UseSplitterReturnValue<T extends HTMLElement = any> {\n /** Ref callback for the container element */\n ref: React.RefCallback<T | null>;\n /** Current panel sizes, each value keeps the unit it was declared in */\n sizes: SplitterPaneSize[];\n /** Whether sizes are tracked in pixels because any pane size, `min`, `max`, `step`, `shiftStep`\n * or `collapseThreshold` uses a fixed `px`/`rem` unit */\n pixelMode: boolean;\n /** Which panels are currently collapsed */\n collapsed: boolean[];\n /** Index of handle being dragged, or -1 */\n activeHandle: number;\n /** Get props to spread on each resize handle */\n getHandleProps: (input: { index: number }) => {\n ref: React.RefCallback<HTMLElement>;\n role: 'separator';\n 'aria-orientation': 'horizontal' | 'vertical';\n 'aria-valuenow': number;\n 'aria-valuemin': number;\n 'aria-valuemax': number;\n tabIndex: number;\n onKeyDown: React.KeyboardEventHandler;\n onDoubleClick: React.MouseEventHandler;\n 'data-active': boolean | undefined;\n 'data-orientation': 'horizontal' | 'vertical';\n };\n /** Programmatically set sizes, each value keeps its declared unit */\n setSizes: (sizes: SplitterPaneSize[]) => void;\n /** Collapse a panel */\n collapse: (panelIndex: number) => void;\n /** Expand a collapsed panel */\n expand: (panelIndex: number) => void;\n /** Toggle collapse of a panel */\n toggleCollapse: (panelIndex: number) => void;\n /** Reset the two panels adjacent to a handle to their default ratio, preserving\n * their combined size */\n reset: (handleIndex: number) => void;\n}\n\nconst PX_RE = /^(-?[\\d.]+)px$/;\nconst REM_RE = /^(-?[\\d.]+)rem$/;\nconst PERCENT_RE = /^(-?[\\d.]+)%$/;\n\nfunction isFixedSize(size: SplitterPaneSize | undefined): boolean {\n return typeof size === 'string' && (PX_RE.test(size) || REM_RE.test(size));\n}\n\nfunction sizeMagnitude(size: SplitterPaneSize): number {\n return typeof size === 'number' ? size : parseFloat(size);\n}\n\nfunction detectPixelMode(options: UseSplitterOptions): boolean {\n return (\n options.panels.some(\n (panel) =>\n isFixedSize(panel.defaultSize) ||\n isFixedSize(panel.min) ||\n isFixedSize(panel.max) ||\n isFixedSize(panel.collapseThreshold)\n ) ||\n isFixedSize(options.step) ||\n isFixedSize(options.shiftStep) ||\n (options.sizes?.some(isFixedSize) ?? false)\n );\n}\n\nfunction getRootFontSize(): number {\n if (typeof window === 'undefined') {\n return 16;\n }\n const fontSize = parseFloat(getComputedStyle(document.documentElement).fontSize);\n return Number.isFinite(fontSize) && fontSize > 0 ? fontSize : 16;\n}\n\nfunction resolveSize(\n size: SplitterPaneSize,\n pixelMode: boolean,\n containerPx: number,\n rootFontSize: number\n): number {\n if (!pixelMode) {\n return sizeMagnitude(size);\n }\n\n if (typeof size === 'number') {\n return (size / 100) * containerPx;\n }\n\n const percent = PERCENT_RE.exec(size);\n if (percent) {\n return (parseFloat(percent[1]) / 100) * containerPx;\n }\n\n const rem = REM_RE.exec(size);\n if (rem) {\n return parseFloat(rem[1]) * rootFontSize;\n }\n\n const px = PX_RE.exec(size);\n if (px) {\n return parseFloat(px[1]);\n }\n\n return 0;\n}\n\n/** Down-scaling factor applied to fixed panes when their combined pixel size overflows the\n * container, so they shrink to fit (matching `resolveWorkingSizes`). Returns `1` when nothing\n * overflows or the layout is not in pixel mode. Encoders divide by this to invert the scaling and\n * persist the original absolute sizes instead of the shrunk-to-fit ones. */\nfunction getFixedScale(\n sizes: SplitterPaneSize[],\n pixelMode: boolean,\n containerPx: number,\n rootFontSize: number\n): number {\n if (!pixelMode) {\n return 1;\n }\n\n let fixedTotal = 0;\n sizes.forEach((size) => {\n if (isFixedSize(size)) {\n fixedTotal += resolveSize(size, true, containerPx, rootFontSize);\n }\n });\n\n return fixedTotal > containerPx && fixedTotal > 0 ? containerPx / fixedTotal : 1;\n}\n\n/** Resolves all sizes to pixels at once. Fixed panes get their absolute pixel size, flexible panes\n * share the leftover space by their weight ratio – matching how the layout is rendered with\n * `flex-grow`, so drag math operates on the same pixel sizes the user sees. */\nfunction resolveWorkingSizes(\n sizes: SplitterPaneSize[],\n pixelMode: boolean,\n containerPx: number,\n rootFontSize: number\n): number[] {\n if (!pixelMode) {\n return sizes.map((size) => sizeMagnitude(size));\n }\n\n let fixedTotal = 0;\n let flexibleWeight = 0;\n sizes.forEach((size) => {\n if (isFixedSize(size)) {\n fixedTotal += resolveSize(size, true, containerPx, rootFontSize);\n } else {\n flexibleWeight += sizeMagnitude(size);\n }\n });\n\n const leftover = Math.max(0, containerPx - fixedTotal);\n const fixedScale = getFixedScale(sizes, pixelMode, containerPx, rootFontSize);\n\n return sizes.map((size) => {\n if (isFixedSize(size)) {\n return resolveSize(size, true, containerPx, rootFontSize) * fixedScale;\n }\n return flexibleWeight > 0 ? (sizeMagnitude(size) / flexibleWeight) * leftover : 0;\n });\n}\n\nfunction encodeSize(\n value: number,\n original: SplitterPaneSize,\n pixelMode: boolean,\n containerPx: number,\n rootFontSize: number,\n fixedScale: number = 1\n): SplitterPaneSize {\n if (!pixelMode) {\n return typeof original === 'string' && PERCENT_RE.test(original) ? `${value}%` : value;\n }\n\n if (typeof original === 'number') {\n return containerPx > 0 ? (value / containerPx) * 100 : original;\n }\n\n if (PERCENT_RE.test(original)) {\n return `${containerPx > 0 ? (value / containerPx) * 100 : parseFloat(original)}%`;\n }\n\n const absolute = fixedScale > 0 ? value / fixedScale : value;\n\n if (REM_RE.test(original)) {\n return `${rootFontSize > 0 ? absolute / rootFontSize : 0}rem`;\n }\n\n return `${absolute}px`;\n}\n\n/** Encodes working pixel sizes back to raw sizes after a resize, keeping the unit each pane was\n * declared in. Panes whose working size did not change keep their original raw value. When fixed\n * panes overflow the container they render down-scaled, so their working sizes are scaled back up to\n * absolute sizes (preserving their declared sizes). If the resize instead hands space to a flexible\n * pane the overflow clears and the layout leaves the down-scaled regime: every pane is then encoded\n * from its current working size – including untouched fixed panes (so they do not jump back to their\n * over-sized value) and untouched flexible panes (so a pane that was squeezed to `0` does not keep a\n * stale weight and steal the freed space on the next render). */\nfunction encodeWorkingSizes(\n nextWorking: number[],\n baseWorking: number[],\n baseRaw: SplitterPaneSize[],\n pixelMode: boolean,\n containerPx: number,\n rootFontSize: number\n): SplitterPaneSize[] {\n const fixedScale = getFixedScale(baseRaw, pixelMode, containerPx, rootFontSize);\n\n let fixedWorkingSum = 0;\n nextWorking.forEach((value, i) => {\n if (isFixedSize(baseRaw[i])) {\n fixedWorkingSum += value;\n }\n });\n const overflowCleared = fixedScale < 1 && fixedWorkingSum < containerPx - 1e-6;\n const encodeScale = overflowCleared ? 1 : fixedScale;\n\n return nextWorking.map((value, i) =>\n overflowCleared || Math.abs(value - baseWorking[i]) > 1e-6\n ? encodeSize(value, baseRaw[i], pixelMode, containerPx, rootFontSize, encodeScale)\n : baseRaw[i]\n );\n}\n\nfunction resolvePanel(\n panel: UseSplitterPanel,\n pixelMode: boolean,\n containerPx: number,\n rootFontSize: number\n): UseSplitterResolvedPanel {\n return {\n defaultSize: resolveSize(panel.defaultSize, pixelMode, containerPx, rootFontSize),\n min: panel.min != null ? resolveSize(panel.min, pixelMode, containerPx, rootFontSize) : 0,\n max:\n panel.max != null\n ? resolveSize(panel.max, pixelMode, containerPx, rootFontSize)\n : pixelMode\n ? containerPx\n : 100,\n collapseThreshold:\n panel.collapseThreshold != null\n ? resolveSize(panel.collapseThreshold, pixelMode, containerPx, rootFontSize)\n : undefined,\n collapsible: panel.collapsible,\n };\n}\n\nfunction resolveStep(\n step: SplitterStep,\n pixelMode: boolean,\n containerPx: number,\n rootFontSize: number\n): number {\n return resolveSize(step, pixelMode, containerPx, rootFontSize);\n}\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.min(Math.max(value, min), max);\n}\n\nfunction getMin(panel: UseSplitterResolvedPanel): number {\n return panel.min ?? 0;\n}\n\nfunction getMax(panel: UseSplitterResolvedPanel): number {\n return panel.max ?? Infinity;\n}\n\nfunction getCollapseThreshold(panel: UseSplitterResolvedPanel): number {\n return panel.collapseThreshold ?? getMin(panel);\n}\n\ninterface SplitterInternalState {\n isDragging: boolean;\n handleIndex: number;\n startPointer: number;\n containerSize: number;\n rootFontSize: number;\n pixelMode: boolean;\n startSizes: number[];\n startRaw: SplitterPaneSize[];\n preCollapseSizes: SplitterPaneSize[];\n}\n\nfunction createInitialInternalState(): SplitterInternalState {\n return {\n isDragging: false,\n handleIndex: -1,\n startPointer: 0,\n containerSize: 0,\n rootFontSize: 16,\n pixelMode: false,\n startSizes: [],\n startRaw: [],\n preCollapseSizes: [],\n };\n}\n\nfunction checkCollapse(\n sizes: number[],\n panels: UseSplitterResolvedPanel[],\n handleIndex: number,\n delta: number\n): number[] | null {\n const beforeIdx = handleIndex;\n const afterIdx = handleIndex + 1;\n const beforePanel = panels[beforeIdx];\n const afterPanel = panels[afterIdx];\n\n const rawBefore = sizes[beforeIdx] + delta;\n const rawAfter = sizes[afterIdx] - delta;\n\n if (\n beforePanel.collapsible &&\n rawBefore < getCollapseThreshold(beforePanel) &&\n rawBefore < sizes[beforeIdx]\n ) {\n const result = [...sizes];\n result[afterIdx] += result[beforeIdx];\n result[beforeIdx] = 0;\n return result;\n }\n\n if (\n afterPanel.collapsible &&\n rawAfter < getCollapseThreshold(afterPanel) &&\n rawAfter < sizes[afterIdx]\n ) {\n const result = [...sizes];\n result[beforeIdx] += result[afterIdx];\n result[afterIdx] = 0;\n return result;\n }\n\n return null;\n}\n\nfunction applyAdjacentOnly(\n sizes: number[],\n panels: UseSplitterResolvedPanel[],\n handleIndex: number,\n delta: number\n): number[] {\n const result = [...sizes];\n const beforeIdx = handleIndex;\n const afterIdx = handleIndex + 1;\n\n const total = result[beforeIdx] + result[afterIdx];\n const effectiveBeforeMax = Math.min(getMax(panels[beforeIdx]), total - getMin(panels[afterIdx]));\n const effectiveBeforeMin = Math.max(getMin(panels[beforeIdx]), total - getMax(panels[afterIdx]));\n const newBefore = clamp(result[beforeIdx] + delta, effectiveBeforeMin, effectiveBeforeMax);\n result[beforeIdx] = newBefore;\n result[afterIdx] = total - newBefore;\n return result;\n}\n\nfunction redistributeNearest(\n sizes: number[],\n panels: UseSplitterResolvedPanel[],\n handleIndex: number,\n delta: number\n): number[] {\n const result = [...sizes];\n\n if (delta > 0) {\n const growIdx = handleIndex;\n const maxGrow = getMax(panels[growIdx]) - result[growIdx];\n const wantedGrow = Math.min(delta, maxGrow);\n\n let taken = 0;\n for (let i = handleIndex + 1; i < result.length && taken < wantedGrow; i += 1) {\n const canGive = result[i] - getMin(panels[i]);\n const take = Math.min(canGive, wantedGrow - taken);\n result[i] -= take;\n taken += take;\n }\n\n result[growIdx] += taken;\n } else if (delta < 0) {\n const growIdx = handleIndex + 1;\n const maxGrow = getMax(panels[growIdx]) - result[growIdx];\n const wantedGrow = Math.min(Math.abs(delta), maxGrow);\n\n let taken = 0;\n for (let i = handleIndex; i >= 0 && taken < wantedGrow; i -= 1) {\n const canGive = result[i] - getMin(panels[i]);\n const take = Math.min(canGive, wantedGrow - taken);\n result[i] -= take;\n taken += take;\n }\n\n result[growIdx] += taken;\n }\n\n return result;\n}\n\nfunction redistributeEqual(\n sizes: number[],\n panels: UseSplitterResolvedPanel[],\n handleIndex: number,\n delta: number\n): number[] {\n const result = [...sizes];\n\n if (delta > 0) {\n const growIdx = handleIndex;\n const maxGrow = getMax(panels[growIdx]) - result[growIdx];\n const wantedGrow = Math.min(delta, maxGrow);\n\n const donors: number[] = [];\n for (let i = handleIndex + 1; i < result.length; i += 1) {\n if (result[i] > getMin(panels[i])) {\n donors.push(i);\n }\n }\n\n let remaining = wantedGrow;\n while (remaining > 0.001 && donors.length > 0) {\n const perDonor = remaining / donors.length;\n const exhausted: number[] = [];\n\n for (let d = 0; d < donors.length; d += 1) {\n const idx = donors[d];\n const canGive = result[idx] - getMin(panels[idx]);\n const take = Math.min(canGive, perDonor);\n result[idx] -= take;\n remaining -= take;\n if (canGive <= perDonor + 0.001) {\n exhausted.push(d);\n }\n }\n\n for (let i = exhausted.length - 1; i >= 0; i -= 1) {\n donors.splice(exhausted[i], 1);\n }\n\n if (exhausted.length === 0) {\n break;\n }\n }\n\n result[growIdx] += wantedGrow - remaining;\n } else if (delta < 0) {\n const growIdx = handleIndex + 1;\n const maxGrow = getMax(panels[growIdx]) - result[growIdx];\n const wantedGrow = Math.min(Math.abs(delta), maxGrow);\n\n const donors: number[] = [];\n for (let i = handleIndex; i >= 0; i -= 1) {\n if (result[i] > getMin(panels[i])) {\n donors.push(i);\n }\n }\n\n let remaining = wantedGrow;\n while (remaining > 0.001 && donors.length > 0) {\n const perDonor = remaining / donors.length;\n const exhausted: number[] = [];\n\n for (let d = 0; d < donors.length; d += 1) {\n const idx = donors[d];\n const canGive = result[idx] - getMin(panels[idx]);\n const take = Math.min(canGive, perDonor);\n result[idx] -= take;\n remaining -= take;\n if (canGive <= perDonor + 0.001) {\n exhausted.push(d);\n }\n }\n\n for (let i = exhausted.length - 1; i >= 0; i -= 1) {\n donors.splice(exhausted[i], 1);\n }\n\n if (exhausted.length === 0) {\n break;\n }\n }\n\n result[growIdx] += wantedGrow - remaining;\n }\n\n return result;\n}\n\nfunction applyConstraints(\n sizes: number[],\n panels: UseSplitterResolvedPanel[],\n handleIndex: number,\n delta: number,\n redistribute?: 'nearest' | 'equal' | UseSplitterRedistributeFn\n): number[] {\n if (typeof redistribute === 'function') {\n return redistribute({ sizes: [...sizes], panels, handleIndex, delta });\n }\n\n if (redistribute === 'nearest' || redistribute === 'equal') {\n const strategy = redistribute === 'nearest' ? redistributeNearest : redistributeEqual;\n const result = strategy(sizes, panels, handleIndex, delta);\n\n const beforeIdx = handleIndex;\n const afterIdx = handleIndex + 1;\n const beforePanel = panels[beforeIdx];\n const afterPanel = panels[afterIdx];\n\n if (\n beforePanel.collapsible &&\n result[beforeIdx] < getCollapseThreshold(beforePanel) &&\n result[beforeIdx] < sizes[beforeIdx]\n ) {\n const freed = result[beforeIdx];\n result[afterIdx] += freed;\n result[beforeIdx] = 0;\n } else if (\n afterPanel.collapsible &&\n result[afterIdx] < getCollapseThreshold(afterPanel) &&\n result[afterIdx] < sizes[afterIdx]\n ) {\n const freed = result[afterIdx];\n result[beforeIdx] += freed;\n result[afterIdx] = 0;\n }\n\n return result;\n }\n\n const collapsed = checkCollapse(sizes, panels, handleIndex, delta);\n if (collapsed) {\n return collapsed;\n }\n\n return applyAdjacentOnly(sizes, panels, handleIndex, delta);\n}\n\nexport function useSplitter<T extends HTMLElement = any>(\n options: UseSplitterOptions\n): UseSplitterReturnValue<T> {\n const {\n panels,\n orientation = 'horizontal',\n sizes: controlledSizes,\n onSizeChange,\n onCollapseChange,\n redistribute,\n step = 1,\n shiftStep = 10,\n dir = 'ltr',\n resetOnDoubleClick = true,\n enabled = true,\n } = options;\n\n const pixelMode = detectPixelMode(options);\n\n const defaultSizes = panels.map((panel) => panel.defaultSize);\n\n const [currentSizes, setCurrentSizes] = useUncontrolled<SplitterPaneSize[]>({\n value: controlledSizes,\n defaultValue: defaultSizes,\n finalValue: defaultSizes,\n onChange: onSizeChange,\n });\n\n const [activeHandle, setActiveHandle] = useState(-1);\n const [containerSize, setContainerSize] = useState(0);\n\n const optionsRef = useRef(options);\n optionsRef.current = options;\n\n const internalStateRef = useRef<SplitterInternalState>(createInitialInternalState());\n const containerRef = useRef<T | null>(null);\n const containerSizeRef = useRef(0);\n const rootFontSizeRef = useRef(16);\n const documentControllerRef = useRef<AbortController | null>(null);\n const frameRef = useRef(0);\n const currentSizesRef = useRef(currentSizes);\n currentSizesRef.current = currentSizes;\n\n const preCollapseSizesRef = useRef<SplitterPaneSize[]>(defaultSizes);\n\n const collapsed = currentSizes.map((size) => sizeMagnitude(size) === 0);\n\n const measureContainer = useCallback(() => {\n const node = containerRef.current;\n if (!node) {\n return 0;\n }\n const rect = node.getBoundingClientRect();\n return (optionsRef.current.orientation ?? 'horizontal') === 'horizontal'\n ? rect.width\n : rect.height;\n }, []);\n\n const updateSizes = useCallback(\n (newSizes: SplitterPaneSize[]) => {\n currentSizesRef.current = newSizes;\n setCurrentSizes(newSizes);\n },\n [setCurrentSizes]\n );\n\n const collapsePanel = useCallback(\n (panelIndex: number) => {\n if (!panels[panelIndex]?.collapsible) {\n return;\n }\n const raw = currentSizesRef.current;\n if (sizeMagnitude(raw[panelIndex]) === 0) {\n return;\n }\n\n const container = pixelMode ? containerSizeRef.current || measureContainer() : 0;\n const rootFontSize = rootFontSizeRef.current;\n const working = resolveWorkingSizes(raw, pixelMode, container, rootFontSize);\n\n preCollapseSizesRef.current = [...raw];\n const freedSize = working[panelIndex];\n working[panelIndex] = 0;\n\n const neighbor = panelIndex === 0 ? 1 : panelIndex - 1;\n working[neighbor] += freedSize;\n\n updateSizes(\n working.map((value, i) => encodeSize(value, raw[i], pixelMode, container, rootFontSize))\n );\n onCollapseChange?.(panelIndex, true);\n },\n [panels, pixelMode, measureContainer, updateSizes, onCollapseChange]\n );\n\n const expandPanel = useCallback(\n (panelIndex: number) => {\n if (!panels[panelIndex]?.collapsible) {\n return;\n }\n const raw = currentSizesRef.current;\n if (sizeMagnitude(raw[panelIndex]) !== 0) {\n return;\n }\n\n const container = pixelMode ? containerSizeRef.current || measureContainer() : 0;\n const rootFontSize = rootFontSizeRef.current;\n const working = resolveWorkingSizes(raw, pixelMode, container, rootFontSize);\n\n const preCollapse = preCollapseSizesRef.current;\n const restoreSource =\n preCollapse[panelIndex] != null && sizeMagnitude(preCollapse[panelIndex]) !== 0\n ? preCollapse[panelIndex]\n : panels[panelIndex].defaultSize;\n const restoreSize = resolveSize(restoreSource, pixelMode, container, rootFontSize);\n\n const neighbor = panelIndex === 0 ? 1 : panelIndex - 1;\n const neighborMin =\n panels[neighbor].min != null\n ? resolveSize(panels[neighbor].min!, pixelMode, container, rootFontSize)\n : 0;\n const available = Math.max(0, working[neighbor] - neighborMin);\n const actualRestore = Math.min(restoreSize, available);\n\n if (actualRestore <= 0) {\n return;\n }\n\n working[panelIndex] = actualRestore;\n working[neighbor] -= actualRestore;\n\n updateSizes(\n working.map((value, i) => encodeSize(value, raw[i], pixelMode, container, rootFontSize))\n );\n onCollapseChange?.(panelIndex, false);\n },\n [panels, pixelMode, measureContainer, updateSizes, onCollapseChange]\n );\n\n const toggleCollapsePanel = useCallback(\n (panelIndex: number) => {\n if (sizeMagnitude(currentSizesRef.current[panelIndex]) === 0) {\n expandPanel(panelIndex);\n } else {\n collapsePanel(panelIndex);\n }\n },\n [collapsePanel, expandPanel]\n );\n\n const emitCollapseTransitions = useCallback(\n (\n prev: SplitterPaneSize[],\n next: number[],\n indices: number[],\n preCollapseSnapshot: SplitterPaneSize[]\n ) => {\n const onChange = optionsRef.current.onCollapseChange;\n for (const idx of indices) {\n const wasCollapsed = sizeMagnitude(prev[idx]) === 0;\n const nowCollapsed = next[idx] === 0;\n if (!wasCollapsed && nowCollapsed) {\n preCollapseSizesRef.current = [...preCollapseSnapshot];\n onChange?.(idx, true);\n } else if (wasCollapsed && !nowCollapsed) {\n onChange?.(idx, false);\n }\n }\n },\n []\n );\n\n const reset = useCallback(\n (handleIndex: number) => {\n const raw = currentSizesRef.current;\n\n const beforeIdx = handleIndex;\n const afterIdx = handleIndex + 1;\n if (beforeIdx < 0 || afterIdx >= raw.length) {\n return;\n }\n\n const container = pixelMode ? containerSizeRef.current || measureContainer() : 0;\n const rootFontSize = rootFontSizeRef.current;\n const working = resolveWorkingSizes(raw, pixelMode, container, rootFontSize);\n const resolvedPanels = optionsRef.current.panels.map((panel) =>\n resolvePanel(panel, pixelMode, container, rootFontSize)\n );\n\n const total = working[beforeIdx] + working[afterIdx];\n const defBefore = resolvedPanels[beforeIdx].defaultSize;\n const defAfter = resolvedPanels[afterIdx].defaultSize;\n const defTotal = defBefore + defAfter;\n const targetBefore = defTotal === 0 ? total / 2 : total * (defBefore / defTotal);\n\n const next = applyAdjacentOnly(\n working,\n resolvedPanels,\n beforeIdx,\n targetBefore - working[beforeIdx]\n );\n emitCollapseTransitions(raw, next, [beforeIdx, afterIdx], raw);\n updateSizes(encodeWorkingSizes(next, working, raw, pixelMode, container, rootFontSize));\n },\n [emitCollapseTransitions, updateSizes, pixelMode, measureContainer]\n );\n\n const containerRefCallback: React.RefCallback<T | null> = useCallback((node) => {\n containerRef.current = node;\n }, []);\n\n useEffect(() => {\n if (!pixelMode || typeof ResizeObserver === 'undefined') {\n return undefined;\n }\n\n const node = containerRef.current;\n if (!node) {\n return undefined;\n }\n\n let frame = 0;\n const update = () => {\n const rect = node.getBoundingClientRect();\n const size =\n (optionsRef.current.orientation ?? 'horizontal') === 'horizontal'\n ? rect.width\n : rect.height;\n rootFontSizeRef.current = getRootFontSize();\n containerSizeRef.current = size;\n setContainerSize((prev) => (prev !== size ? size : prev));\n };\n\n const observer = new ResizeObserver(() => {\n cancelAnimationFrame(frame);\n frame = requestAnimationFrame(update);\n });\n\n observer.observe(node);\n update();\n\n return () => {\n cancelAnimationFrame(frame);\n observer.disconnect();\n };\n }, [pixelMode, orientation]);\n\n const handleRefCallbacks = useRef<Map<number, (node: HTMLElement | null) => void>>(new Map());\n const handleElementControllers = useRef<Map<number, AbortController>>(new Map());\n\n const getHandleRefCallback = useCallback(\n (handleIndex: number): React.RefCallback<HTMLElement> => {\n if (handleRefCallbacks.current.has(handleIndex)) {\n return handleRefCallbacks.current.get(handleIndex)!;\n }\n\n const callback = (node: HTMLElement | null) => {\n const existingController = handleElementControllers.current.get(handleIndex);\n if (existingController) {\n existingController.abort();\n handleElementControllers.current.delete(handleIndex);\n }\n\n if (!node) {\n return;\n }\n\n const elementController = new AbortController();\n handleElementControllers.current.set(handleIndex, elementController);\n\n const onPointerDown = (event: PointerEvent) => {\n if (optionsRef.current.enabled === false) {\n return;\n }\n if (event.button !== 0) {\n return;\n }\n\n const container = containerRef.current;\n if (!container) {\n return;\n }\n\n const opts = optionsRef.current;\n const isHorizontal = (opts.orientation ?? 'horizontal') === 'horizontal';\n const rect = container.getBoundingClientRect();\n const containerSizePx = isHorizontal ? rect.width : rect.height;\n const pointerPos = isHorizontal ? event.clientX : event.clientY;\n const isPixelMode = detectPixelMode(opts);\n const rootFontSize = getRootFontSize();\n\n const s = internalStateRef.current;\n s.isDragging = true;\n s.handleIndex = handleIndex;\n s.startPointer = pointerPos;\n s.containerSize = containerSizePx;\n s.rootFontSize = rootFontSize;\n s.pixelMode = isPixelMode;\n s.startRaw = [...currentSizesRef.current];\n s.startSizes = resolveWorkingSizes(\n s.startRaw,\n isPixelMode,\n containerSizePx,\n rootFontSize\n );\n s.preCollapseSizes = [...preCollapseSizesRef.current];\n\n setActiveHandle(handleIndex);\n document.body.style.userSelect = 'none';\n document.body.style.webkitUserSelect = 'none';\n document.body.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n\n opts.onResizeStart?.(handleIndex);\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', onPointerUp, { signal: sig });\n };\n\n const flushResize = (pointerEvent: PointerEvent) => {\n const s = internalStateRef.current;\n if (!s.containerSize) {\n return;\n }\n const opts = optionsRef.current;\n const isHorizontal = (opts.orientation ?? 'horizontal') === 'horizontal';\n const isRtl = isHorizontal && opts.dir === 'rtl';\n const pointerPos = isHorizontal ? pointerEvent.clientX : pointerEvent.clientY;\n const pixelDelta = (isRtl ? -1 : 1) * (pointerPos - s.startPointer);\n const delta = s.pixelMode ? pixelDelta : (pixelDelta / s.containerSize) * 100;\n\n const resolvedPanels = opts.panels.map((panel) =>\n resolvePanel(panel, s.pixelMode, s.containerSize, s.rootFontSize)\n );\n\n const newSizes = applyConstraints(\n s.startSizes,\n resolvedPanels,\n s.handleIndex,\n delta,\n opts.redistribute\n );\n\n const prevSizes = currentSizesRef.current;\n emitCollapseTransitions(\n prevSizes,\n newSizes,\n [s.handleIndex, s.handleIndex + 1],\n s.startRaw\n );\n\n const encoded = encodeWorkingSizes(\n newSizes,\n s.startSizes,\n s.startRaw,\n s.pixelMode,\n s.containerSize,\n s.rootFontSize\n );\n currentSizesRef.current = encoded;\n setCurrentSizes(encoded);\n };\n\n const onPointerMove = (event: PointerEvent) => {\n const s = internalStateRef.current;\n if (!s.isDragging) {\n return;\n }\n\n cancelAnimationFrame(frameRef.current);\n frameRef.current = requestAnimationFrame(() => {\n flushResize(event);\n });\n };\n\n const onPointerUp = (event: PointerEvent) => {\n const s = internalStateRef.current;\n if (!s.isDragging) {\n return;\n }\n\n cancelAnimationFrame(frameRef.current);\n flushResize(event);\n\n s.isDragging = false;\n const finishedHandle = s.handleIndex;\n s.handleIndex = -1;\n\n setActiveHandle(-1);\n document.body.style.userSelect = '';\n document.body.style.webkitUserSelect = '';\n document.body.style.cursor = '';\n\n documentControllerRef.current?.abort();\n documentControllerRef.current = null;\n\n optionsRef.current.onResizeEnd?.(finishedHandle, [...currentSizesRef.current]);\n };\n\n node.addEventListener('pointerdown', onPointerDown, {\n signal: elementController.signal,\n });\n };\n\n handleRefCallbacks.current.set(handleIndex, callback);\n return callback;\n },\n [setCurrentSizes]\n );\n\n const getHandleProps = useCallback(\n (input: { index: number }) => {\n const { index } = input;\n const orient = orientation;\n const rootFontSize = rootFontSizeRef.current;\n const working = resolveWorkingSizes(currentSizes, pixelMode, containerSize, rootFontSize);\n const resolvedPanels = panels.map((panel) =>\n resolvePanel(panel, pixelMode, containerSize, rootFontSize)\n );\n const beforeSize = working[index] ?? 0;\n const beforePanel = resolvedPanels[index];\n\n return {\n ref: getHandleRefCallback(index),\n role: 'separator' as const,\n 'aria-orientation': orient,\n 'aria-valuenow': Math.round(beforeSize),\n 'aria-valuemin': Math.round(getMin(beforePanel)),\n 'aria-valuemax': Math.round(getMax(beforePanel)),\n tabIndex: 0,\n onKeyDown: (event: React.KeyboardEvent) => {\n if (!enabled) {\n return;\n }\n\n const isHorizontal = orient === 'horizontal';\n const isRtl = dir === 'rtl';\n\n const container = pixelMode ? containerSizeRef.current || measureContainer() : 0;\n const liveRootFontSize = rootFontSizeRef.current;\n const liveWorking = resolveWorkingSizes(\n currentSizes,\n pixelMode,\n container,\n liveRootFontSize\n );\n const livePanels = panels.map((panel) =>\n resolvePanel(panel, pixelMode, container, liveRootFontSize)\n );\n const liveBeforePanel = livePanels[index];\n const liveAfterPanel = livePanels[index + 1];\n\n let delta = 0;\n const currentStep = resolveStep(\n event.shiftKey ? shiftStep : step,\n pixelMode,\n container,\n liveRootFontSize\n );\n\n switch (event.key) {\n case 'ArrowLeft': {\n if (!isHorizontal) {\n return;\n }\n delta = isRtl ? currentStep : -currentStep;\n break;\n }\n case 'ArrowRight': {\n if (!isHorizontal) {\n return;\n }\n delta = isRtl ? -currentStep : currentStep;\n break;\n }\n case 'ArrowUp': {\n if (isHorizontal) {\n return;\n }\n delta = -currentStep;\n break;\n }\n case 'ArrowDown': {\n if (isHorizontal) {\n return;\n }\n delta = currentStep;\n break;\n }\n case 'Home': {\n delta = -(liveWorking[index] - getMin(liveBeforePanel));\n break;\n }\n case 'End': {\n delta = getMax(liveBeforePanel) - liveWorking[index];\n break;\n }\n case 'Enter': {\n const beforeCollapsible = liveBeforePanel?.collapsible;\n const afterCollapsible = liveAfterPanel?.collapsible;\n\n if (beforeCollapsible && liveWorking[index] <= liveWorking[index + 1]) {\n toggleCollapsePanel(index);\n event.preventDefault();\n return;\n }\n if (afterCollapsible) {\n toggleCollapsePanel(index + 1);\n event.preventDefault();\n return;\n }\n if (beforeCollapsible) {\n toggleCollapsePanel(index);\n event.preventDefault();\n return;\n }\n return;\n }\n default:\n return;\n }\n\n event.preventDefault();\n\n if (delta !== 0) {\n const newSizes = applyConstraints(liveWorking, livePanels, index, delta, redistribute);\n emitCollapseTransitions(currentSizes, newSizes, [index, index + 1], currentSizes);\n updateSizes(\n encodeWorkingSizes(\n newSizes,\n liveWorking,\n currentSizes,\n pixelMode,\n container,\n liveRootFontSize\n )\n );\n }\n },\n onDoubleClick: () => {\n if (!enabled || !resetOnDoubleClick) {\n return;\n }\n reset(index);\n },\n 'data-active': activeHandle === index || undefined,\n 'data-orientation': orient,\n };\n },\n [\n orientation,\n currentSizes,\n panels,\n pixelMode,\n containerSize,\n enabled,\n dir,\n step,\n shiftStep,\n resetOnDoubleClick,\n activeHandle,\n redistribute,\n measureContainer,\n getHandleRefCallback,\n toggleCollapsePanel,\n updateSizes,\n emitCollapseTransitions,\n reset,\n ]\n );\n\n useEffect(\n () => () => {\n documentControllerRef.current?.abort();\n documentControllerRef.current = null;\n handleElementControllers.current.forEach((controller) => controller.abort());\n handleElementControllers.current.clear();\n cancelAnimationFrame(frameRef.current);\n\n if (internalStateRef.current.isDragging) {\n internalStateRef.current.isDragging = false;\n document.body.style.userSelect = '';\n document.body.style.webkitUserSelect = '';\n document.body.style.cursor = '';\n }\n },\n []\n );\n\n return {\n ref: containerRefCallback,\n sizes: currentSizes,\n pixelMode,\n collapsed,\n activeHandle,\n getHandleProps,\n setSizes: updateSizes,\n collapse: collapsePanel,\n expand: expandPanel,\n toggleCollapse: toggleCollapsePanel,\n reset,\n };\n}\n\nexport namespace useSplitter {\n export type Panel = UseSplitterPanel;\n export type Options = UseSplitterOptions;\n export type RedistributeInput = UseSplitterRedistributeInput;\n export type RedistributeFn = UseSplitterRedistributeFn;\n export type ResolvedPanel = UseSplitterResolvedPanel;\n export type ReturnValue<T extends HTMLElement = any> = UseSplitterReturnValue<T>;\n export type PaneSize = SplitterPaneSize;\n export type Step = SplitterStep;\n}\n"],"mappings":"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"}