UNPKG

@syncfusion/ej2-spreadsheet

Version:

Feature-rich JavaScript Spreadsheet (Excel) control with built-in support for selection, editing, formatting, importing and exporting to Excel

88 lines (72 loc) 5.93 kB
# Scroll Module data flow ## What It Does The Scroll module coordinates scrolling behavior across headers, main content, and virtualized viewports. Two-layer architecture: **Scroll (UI)** handles user input (wheel, pointer/touch, programmatic scroll events), computes offsets and visible ranges; **Workbook/Render (Core)** supplies row/column sizes and receives updated viewport indexes to render new content. ## Entry Points **Scroll (UI Layer)** - `constructor(parent)` / `addEventListener()` - initialize listeners and properties. - `onContentScroll(e: ScrollEventArgs)` - central handler for horizontal/vertical scrolling updates. - `getRowOffset(scrollTop, scrollDown)` / `getColOffset(scrollLeft, increase, skipHidden)` - map pixel scroll values to sheet row/column indexes and cumulative sizes. - `updateTopLeftCell(increase, isLeft?)` - update the sheet's top-left cell based on offsets. - `updateContainers()` - refresh floating containers like notes/comments on scroll. - `setScrollEvent()` - attach DOM scroll/wheel handlers for headers and content. - `onHeaderWheel(e)` / `onContentWheel(e)` - handle wheel events and apply horizontal/vertical scrolling (including Shift key behavior). - `setClientX()`, `onTouchScroll()` / `pointerUpHandler()` - touch/pointer based scrolling support. - `updateScrollValue(args)` - externally adjust internal offset bookkeeping for coordinated scrolls. - `contentLoaded(args)` / `initProps()` / `destroy()` - lifecycle and cleanup. **Workbook / Render (Core Layer)** - `getRowHeight(sheet, idx, includeHidden?)` / `getColumnWidth(sheet, idx, skipHidden?, includeHidden?)` - provide per-row/col pixel sizes used by offset calculations. - `skipHiddenIdx(sheet, index, fromTop, type?)` - map through hidden rows/cols when computing indexes. - `getCellAddress(row, col)` - used when triggering refresh ranges for non-virtual expansion. - `renderModule.refreshUI(...)` - invoked to materialize additional rows/columns when non-virtual thresholds are crossed. - `sheetModule.getScrollSize()` - used for non-virtual scroll track sizing. - Event notifications used/raised: `onHorizontalScroll`, `onVerticalScroll`, `updateNoteContainer`, `removeCommentContainer`, `focusRenameInput`, `virtualContentLoaded`, `colWidthChanged`. ## Core Logic Flow ``` Page load / contentLoaded() → initProps() and setScrollEvent() ↓ User scrolls (wheel/drag/touch) or programmatic scroll → onContentScroll(e) ↓ Compute left/top pixel positions → translate to offsets via getColOffset/getRowOffset ↓ updateTopLeftCell() → parent.updateTopLeftCell(...) updates active top-left indexes ↓ Notify systems: focusRenameInput, onHorizontalScroll/onVerticalScroll ↓ Update floating containers (notes/comments) and refresh UI if non-virtual thresholds reached ↓ Persist prevScroll / offset state for subsequent scroll deltas ``` ## Operations Handled 1. Pixel-to-index translation: map `scrollLeft`/`scrollTop` to logical row/column indexes and cumulative sizes. 2. Virtualization-aware scrolling: compute when to request new row/column rendering and expand non-virtual dimensions when approaching end-of-sheet. 3. Wheel & header-wheel handling: prevent default behaviour as needed, support horizontal/vertical scrolls and Shift-key acceleration. 4. Touch/pointer scrolling: pointer/touch move handling with delta threshold and RAF-optimized scroll updates. 5. Container updates: notify note/comment containers and rename/focus handlers on scroll. 6. RTL support: initialize `initScrollValue` and translate `scrollLeft` accordingly for RTL scrolling. 7. External scroll syncing: `updateScrollValue` allows other modules to adjust internal offsets when their scroll content changes. ## Scroll Modes | Mode | Behavior | |------|----------| | WheelScroll | Mouse-wheel driven vertical/horizontal scroll, with Shift modifier support. | | ProgrammaticScroll | `updateScroll` / `onContentScroll` invoked by code to set scroll positions. | | TouchScroll | Touch/pointer based horizontal scrolling using `pointermove`/`touchmove` with RAF updates. | | VirtualScroll | Virtualized viewport calculations using `getRowOffset`/`getColOffset` to drive incremental rendering. | ## Validation & Safety - **Virtualization bounds:** Respect `scrollSettings.enableVirtualization` and `isFinite` to avoid requesting rendering beyond allowed limits. - **Hidden rows/cols:** Use `skipHiddenIdx`/`getColumnWidth` with `skipHidden` flags to ensure offsets map correctly around hidden items. - **Small scroll jitter:** Compare rounded values and allow 1px tolerance to account for rendering differences across devices/resolutions. - **RTL adjustments:** Normalize `scrollLeft` to `initScrollValue` when RTL is enabled. - **Prevent default where needed:** Wheel handlers call `preventDefault()` when appropriate to avoid native browser overscroll. - **Touch filtering:** Ignore pointer events originated from mouse in touch handlers; use `selectionStatus` to detect overlay/touch selection interactions. ## Desired Outputs **User-Facing:** - Smooth, responsive scrolling across headers and main content. - Correct cursor/wheel behavior with Shift and touch interactions. - Floating note/comment containers and rename inputs remain correctly positioned during scroll. - Seamless virtualization experience: content loads as the user approaches the viewport edge. **System-Level:** - Accurate `offset` bookkeeping: `offset.left` and `offset.top` store `{ idx, size }` for current viewport. - Notifications emitted: `onHorizontalScroll`, `onVerticalScroll`, `updateNoteContainer`, `removeCommentContainer`, `focusRenameInput`. - Triggered render refreshes when non-virtual thresholds are crossed (via `renderModule.refreshUI`). - Internal `prevScroll` updated to enable delta calculations and avoid redundant work. - Compatibility with RTL, high-DPI, and mixed input (mouse/touch) environments.