diff --git a/web/src/components/RealtimeTable/RealtimeTable.jsx b/web/src/components/RealtimeTable/RealtimeTable.jsx index 539e4b3..dc373f3 100644 --- a/web/src/components/RealtimeTable/RealtimeTable.jsx +++ b/web/src/components/RealtimeTable/RealtimeTable.jsx @@ -20,6 +20,7 @@ import { BASE_TABLE_CONFIG, TABLE_ROW_HEIGHT, getTableBodyCellProps, getTablePap import { useRealtimeActions, useVspOptions } from './contexts/RealtimeContext'; import { useColumnSettings } from './hooks/useColumnSettings'; import { useHeaderPortal } from './hooks/useHeaderPortal'; +import { useWheelScrollStep } from './hooks/useWheelScrollStep'; import { useTableScale } from './hooks/useTableScale'; import { useBudgetYear } from './hooks/useBudgetYear'; import { useValidationRules } from './hooks/useValidationRules'; @@ -158,6 +159,7 @@ const RealtimeTable = ({ formType, formId, sheetName, direction, year }) => { } = useColumnSettings(`${formId}_${formType}_${sheetName}_${direction}`); const { headerPortalRef, containerRef } = useHeaderPortal(); + useWheelScrollStep(containerRef); const rowVirtualizerRef = useRef(null); const columnVirtualizerRef = useRef(null); diff --git a/web/src/components/RealtimeTable/hooks/useWheelScrollStep.js b/web/src/components/RealtimeTable/hooks/useWheelScrollStep.js new file mode 100644 index 0000000..39e411c --- /dev/null +++ b/web/src/components/RealtimeTable/hooks/useWheelScrollStep.js @@ -0,0 +1,22 @@ +import { useEffect } from 'react'; +import { canScrollBy, getWheelScrollDelta } from '../utils/wheelScroll'; + +// Внутри полей ввода и выпадающих списков колесо работает как обычно. +const NATIVE_WHEEL_SELECTOR = 'textarea, select, input, [role="listbox"]'; + +export const useWheelScrollStep = (containerRef) => { + useEffect(() => { + const el = containerRef.current; + if (!el) return undefined; + const onWheel = (event) => { + if (event.target instanceof Element && event.target.closest(NATIVE_WHEEL_SELECTOR)) return; + const delta = getWheelScrollDelta(event); + if (delta === null || !canScrollBy(el, delta)) return; + event.preventDefault(); + el.scrollTop += delta; + }; + // passive: false — иначе preventDefault не работает. + el.addEventListener('wheel', onWheel, { passive: false }); + return () => el.removeEventListener('wheel', onWheel); + }, [containerRef]); +};