@vuu-ui/vuu-table 0.13.113-alpha.2 → 0.13.114

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.
@@ -21,7 +21,7 @@ const useDataSource = ({
21
21
  const data = react.useRef([]);
22
22
  const isMounted = react.useRef(true);
23
23
  const hasUpdated = react.useRef(false);
24
- const rangeRef = react.useRef(vuuUtils.NULL_RANGE);
24
+ const rangeRef = react.useRef(dataSource.range);
25
25
  const totalRowCountRef = react.useRef(0);
26
26
  const rowAutoSelected = react.useRef(false);
27
27
  const autoSelect = autoSelectRowKey ?? (autoSelectFirstRow || selectionModel === "single-no-deselect");
@@ -43,15 +43,10 @@ const useDataSource = ({
43
43
  }
44
44
  };
45
45
  }, [autoSelect, dataSource, handleConfigChange]);
46
- const dataWindow = react.useMemo(() => new movingWindow.MovingWindow(vuuUtils.NULL_RANGE), []);
47
- react.useMemo(() => {
48
- dataSource.on("resumed", () => {
49
- const { range } = dataSource;
50
- if (range.to !== 0) {
51
- dataWindow.setRange(dataSource.range.withBuffer);
52
- }
53
- });
54
- }, [dataSource, dataWindow]);
46
+ const dataWindow = react.useMemo(
47
+ () => new movingWindow.MovingWindow(rangeRef.current.withBuffer),
48
+ []
49
+ );
55
50
  const setData = react.useCallback(
56
51
  (updates) => {
57
52
  for (const row of updates) {
@@ -133,19 +128,6 @@ const useDataSource = ({
133
128
  const getSelectedRows = react.useCallback(() => {
134
129
  return dataWindow.getSelectedRows();
135
130
  }, [dataWindow]);
136
- react.useEffect(() => {
137
- isMounted.current = true;
138
- if (dataSource.status !== "initialising") {
139
- dataSource.resume?.(datasourceMessageHandler);
140
- }
141
- return () => {
142
- isMounted.current = false;
143
- dataSource.suspend?.(
144
- suspenseProps?.escalateToDisable,
145
- suspenseProps?.escalateDelay
146
- );
147
- };
148
- }, [dataSource, datasourceMessageHandler, suspenseProps]);
149
131
  react.useEffect(() => {
150
132
  if (dataSource.status === "disabled") {
151
133
  dataSource.enable?.(datasourceMessageHandler);
@@ -160,7 +142,7 @@ const useDataSource = ({
160
142
  renderBufferSize
161
143
  );
162
144
  dataWindow.setRange(range.withBuffer);
163
- if (dataSource.status !== "subscribed" && dataSource.status !== "subscribing") {
145
+ if (dataSource.status !== "subscribed" && dataSource.status !== "subscribing" && dataSource.status !== "enabling") {
164
146
  dataSource?.subscribe(
165
147
  {
166
148
  range,
@@ -183,6 +165,23 @@ const useDataSource = ({
183
165
  revealSelected
184
166
  ]
185
167
  );
168
+ react.useEffect(() => {
169
+ isMounted.current = true;
170
+ if (dataSource.status !== "initialising") {
171
+ dataSource.resume?.(datasourceMessageHandler);
172
+ if (dataSource.range.from > 0) {
173
+ const { from, to } = rangeRef.current.reset;
174
+ setRange({ from, to });
175
+ }
176
+ }
177
+ return () => {
178
+ isMounted.current = false;
179
+ dataSource.suspend?.(
180
+ suspenseProps?.escalateToDisable,
181
+ suspenseProps?.escalateDelay
182
+ );
183
+ };
184
+ }, [dataSource, datasourceMessageHandler, setRange, suspenseProps]);
186
185
  const removeColumnDataFromCache = react.useCallback(
187
186
  (indexOfRemovedColumn) => {
188
187
  dataWindow.spliceDataAtIndex(indexOfRemovedColumn);
@@ -1 +1 @@
1
- {"version":3,"file":"useDataSource.js","sources":["../../../../packages/vuu-table/src/table-data-source/useDataSource.ts"],"sourcesContent":["import type {\n DataSourceConfigChangeHandler,\n DataSourceRow,\n DataSourceSubscribeCallback,\n DataSourceSubscribedMessage,\n DataSourceSuspenseProps,\n} from \"@vuu-ui/vuu-data-types\";\nimport { SelectRowRequest, VuuRange } from \"@vuu-ui/vuu-protocol-types\";\nimport { NULL_RANGE, Range } from \"@vuu-ui/vuu-utils\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { TableProps } from \"../Table\";\nimport { metadataKeys } from \"@vuu-ui/vuu-utils\";\nimport { TableRowSelectHandlerInternal } from \"@vuu-ui/vuu-table-types\";\nimport { MovingWindow } from \"./moving-window\";\n\nconst { KEY } = metadataKeys;\n\nexport interface DataSourceHookProps\n extends Pick<\n TableProps,\n | \"autoSelectFirstRow\"\n | \"autoSelectRowKey\"\n | \"dataSource\"\n | \"renderBufferSize\"\n | \"revealSelected\"\n | \"selectionModel\"\n > {\n suspenseProps?: DataSourceSuspenseProps;\n onSelect: TableRowSelectHandlerInternal;\n onSizeChange: (size: number) => void;\n onSubscribed: (subscription: DataSourceSubscribedMessage) => void;\n}\n\nexport const useDataSource = ({\n autoSelectFirstRow,\n autoSelectRowKey,\n dataSource,\n onSizeChange,\n onSubscribed,\n renderBufferSize = 0,\n revealSelected,\n onSelect,\n selectionModel,\n suspenseProps,\n}: DataSourceHookProps) => {\n const [, forceUpdate] = useState<unknown>(null);\n const data = useRef<DataSourceRow[]>([]);\n const isMounted = useRef(true);\n const hasUpdated = useRef(false);\n const rangeRef = useRef<Range>(NULL_RANGE);\n const totalRowCountRef = useRef(0);\n const rowAutoSelected = useRef(false);\n\n const autoSelect =\n autoSelectRowKey ??\n (autoSelectFirstRow || selectionModel === \"single-no-deselect\");\n\n const handleConfigChange = useCallback<DataSourceConfigChangeHandler>(\n (_config, _range, _confirmed, configChanges) => {\n if (configChanges?.filterChanged) {\n rowAutoSelected.current = false;\n }\n },\n [],\n );\n\n useEffect(() => {\n if (autoSelect) {\n dataSource.on(\"config\", handleConfigChange);\n }\n return () => {\n if (autoSelect) {\n dataSource.removeListener(\"config\", handleConfigChange);\n }\n };\n }, [autoSelect, dataSource, handleConfigChange]);\n\n const dataWindow = useMemo(() => new MovingWindow(NULL_RANGE), []);\n\n useMemo(() => {\n dataSource.on(\"resumed\", () => {\n // When we resume a dataSource (after switching tabs etc)\n // client will receive rows. We may not have received any\n // setRange calls at this point so dataWindow range will\n //not yet be set. If the dataWindow range is already set,\n // this is a no-op.\n const { range } = dataSource;\n if (range.to !== 0) {\n dataWindow.setRange(dataSource.range.withBuffer);\n }\n });\n }, [dataSource, dataWindow]);\n\n const setData = useCallback(\n (updates: DataSourceRow[]) => {\n for (const row of updates) {\n dataWindow.add(row);\n }\n data.current = dataWindow.data;\n if (isMounted.current) {\n // TODO do we ever need to worry about missing updates here ?\n forceUpdate({});\n }\n },\n [dataWindow],\n );\n\n const selectRow = useCallback(\n (row: DataSourceRow) => {\n const rowKey = row[KEY];\n dataSource.select?.({\n preserveExistingSelection: false,\n rowKey,\n type: \"SELECT_ROW\",\n } as SelectRowRequest);\n onSelect?.(row);\n },\n [dataSource, onSelect],\n );\n\n const datasourceMessageHandler: DataSourceSubscribeCallback = useCallback(\n (message) => {\n if (message.type === \"subscribed\") {\n onSubscribed?.(message);\n } else if (message.type === \"viewport-update\") {\n if (typeof message.size === \"number\") {\n onSizeChange?.(message.size);\n const size = dataWindow.data.length;\n dataWindow.setRowCount(message.size);\n totalRowCountRef.current = message.size;\n\n if (dataWindow.data.length < size) {\n if (isMounted.current === false) {\n console.log(\"setting state whilst unmounted\");\n }\n\n forceUpdate({});\n }\n }\n if (message.rows) {\n setData(message.rows);\n if (autoSelect && rowAutoSelected.current === false) {\n // OR if no selected row in message.rows, e.g after a filter\n rowAutoSelected.current = true;\n if (typeof autoSelect === \"string\") {\n const row = message.rows.find((row) => row[KEY] === autoSelect);\n if (row) {\n selectRow(row);\n } else {\n console.warn(\n `[useDataSource] autoSelect row key ${autoSelect} not in viewport`,\n );\n }\n } else if (message.rows.length > 0) {\n selectRow(message.rows[0]);\n }\n }\n } else if (message.size === 0) {\n setData([]);\n } else if (typeof message.size === \"number\") {\n data.current = dataWindow.data;\n hasUpdated.current = true;\n }\n } else if (message.type === \"viewport-clear\") {\n onSizeChange?.(0);\n dataWindow.setRowCount(0);\n setData([]);\n\n if (isMounted.current === false) {\n console.log(\"setting state whilst unmounted\");\n }\n\n forceUpdate({});\n } else {\n console.log(`useDataSource unexpected message ${message.type}`);\n }\n },\n [autoSelect, dataWindow, onSizeChange, onSubscribed, selectRow, setData],\n );\n\n const getSelectedRows = useCallback(() => {\n return dataWindow.getSelectedRows();\n }, [dataWindow]);\n\n useEffect(() => {\n isMounted.current = true;\n if (dataSource.status !== \"initialising\") {\n dataSource.resume?.(datasourceMessageHandler);\n }\n return () => {\n isMounted.current = false;\n dataSource.suspend?.(\n suspenseProps?.escalateToDisable,\n suspenseProps?.escalateDelay,\n );\n };\n }, [dataSource, datasourceMessageHandler, suspenseProps]);\n\n useEffect(() => {\n if (dataSource.status === \"disabled\") {\n dataSource.enable?.(datasourceMessageHandler);\n }\n }, [dataSource, datasourceMessageHandler]);\n\n const setRange = useCallback(\n (viewportRange: VuuRange) => {\n if (!rangeRef.current.equals(viewportRange)) {\n const range = Range(\n viewportRange.from,\n viewportRange.to,\n renderBufferSize,\n );\n\n dataWindow.setRange(range.withBuffer);\n\n if (\n dataSource.status !== \"subscribed\" &&\n dataSource.status !== \"subscribing\"\n ) {\n dataSource?.subscribe(\n {\n range,\n revealSelected,\n selectedKeyValues: autoSelectRowKey\n ? [autoSelectRowKey]\n : undefined,\n },\n datasourceMessageHandler,\n );\n } else {\n dataSource.range = rangeRef.current = range;\n }\n }\n },\n [\n autoSelectRowKey,\n dataSource,\n dataWindow,\n datasourceMessageHandler,\n renderBufferSize,\n revealSelected,\n ],\n );\n\n const removeColumnDataFromCache = useCallback(\n (indexOfRemovedColumn: number) => {\n dataWindow.spliceDataAtIndex(indexOfRemovedColumn);\n data.current = dataWindow.data;\n },\n [dataWindow],\n );\n\n return {\n data: data.current,\n dataRef: data,\n getSelectedRows,\n range: rangeRef.current,\n removeColumnDataFromCache,\n setRange,\n };\n};\n"],"names":["metadataKeys","useState","useRef","NULL_RANGE","useCallback","useEffect","useMemo","MovingWindow","row","Range"],"mappings":"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"}
1
+ {"version":3,"file":"useDataSource.js","sources":["../../../../packages/vuu-table/src/table-data-source/useDataSource.ts"],"sourcesContent":["import type {\n DataSourceConfigChangeHandler,\n DataSourceRow,\n DataSourceSubscribeCallback,\n DataSourceSubscribedMessage,\n DataSourceSuspenseProps,\n} from \"@vuu-ui/vuu-data-types\";\nimport { SelectRowRequest, VuuRange } from \"@vuu-ui/vuu-protocol-types\";\nimport { Range } from \"@vuu-ui/vuu-utils\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { TableProps } from \"../Table\";\nimport { metadataKeys } from \"@vuu-ui/vuu-utils\";\nimport { TableRowSelectHandlerInternal } from \"@vuu-ui/vuu-table-types\";\nimport { MovingWindow } from \"./moving-window\";\n\nconst { KEY } = metadataKeys;\n\nexport interface DataSourceHookProps\n extends Pick<\n TableProps,\n | \"autoSelectFirstRow\"\n | \"autoSelectRowKey\"\n | \"dataSource\"\n | \"renderBufferSize\"\n | \"revealSelected\"\n | \"selectionModel\"\n > {\n suspenseProps?: DataSourceSuspenseProps;\n onSelect: TableRowSelectHandlerInternal;\n onSizeChange: (size: number) => void;\n onSubscribed: (subscription: DataSourceSubscribedMessage) => void;\n}\n\nexport const useDataSource = ({\n autoSelectFirstRow,\n autoSelectRowKey,\n dataSource,\n onSizeChange,\n onSubscribed,\n renderBufferSize = 0,\n revealSelected,\n onSelect,\n selectionModel,\n suspenseProps,\n}: DataSourceHookProps) => {\n const [, forceUpdate] = useState<unknown>(null);\n const data = useRef<DataSourceRow[]>([]);\n const isMounted = useRef(true);\n const hasUpdated = useRef(false);\n const rangeRef = useRef<Range>(dataSource.range);\n const totalRowCountRef = useRef(0);\n const rowAutoSelected = useRef(false);\n\n const autoSelect =\n autoSelectRowKey ??\n (autoSelectFirstRow || selectionModel === \"single-no-deselect\");\n\n const handleConfigChange = useCallback<DataSourceConfigChangeHandler>(\n (_config, _range, _confirmed, configChanges) => {\n if (configChanges?.filterChanged) {\n rowAutoSelected.current = false;\n }\n },\n [],\n );\n\n useEffect(() => {\n if (autoSelect) {\n dataSource.on(\"config\", handleConfigChange);\n }\n return () => {\n if (autoSelect) {\n dataSource.removeListener(\"config\", handleConfigChange);\n }\n };\n }, [autoSelect, dataSource, handleConfigChange]);\n\n const dataWindow = useMemo(\n () => new MovingWindow(rangeRef.current.withBuffer),\n [],\n );\n\n const setData = useCallback(\n (updates: DataSourceRow[]) => {\n for (const row of updates) {\n dataWindow.add(row);\n }\n data.current = dataWindow.data;\n if (isMounted.current) {\n // TODO do we ever need to worry about missing updates here ?\n forceUpdate({});\n }\n },\n [dataWindow],\n );\n\n const selectRow = useCallback(\n (row: DataSourceRow) => {\n const rowKey = row[KEY];\n dataSource.select?.({\n preserveExistingSelection: false,\n rowKey,\n type: \"SELECT_ROW\",\n } as SelectRowRequest);\n onSelect?.(row);\n },\n [dataSource, onSelect],\n );\n\n const datasourceMessageHandler: DataSourceSubscribeCallback = useCallback(\n (message) => {\n if (message.type === \"subscribed\") {\n onSubscribed?.(message);\n } else if (message.type === \"viewport-update\") {\n if (typeof message.size === \"number\") {\n onSizeChange?.(message.size);\n const size = dataWindow.data.length;\n dataWindow.setRowCount(message.size);\n totalRowCountRef.current = message.size;\n\n if (dataWindow.data.length < size) {\n if (isMounted.current === false) {\n console.log(\"setting state whilst unmounted\");\n }\n\n forceUpdate({});\n }\n }\n if (message.rows) {\n setData(message.rows);\n if (autoSelect && rowAutoSelected.current === false) {\n // OR if no selected row in message.rows, e.g after a filter\n rowAutoSelected.current = true;\n if (typeof autoSelect === \"string\") {\n const row = message.rows.find((row) => row[KEY] === autoSelect);\n if (row) {\n selectRow(row);\n } else {\n console.warn(\n `[useDataSource] autoSelect row key ${autoSelect} not in viewport`,\n );\n }\n } else if (message.rows.length > 0) {\n selectRow(message.rows[0]);\n }\n }\n } else if (message.size === 0) {\n setData([]);\n } else if (typeof message.size === \"number\") {\n data.current = dataWindow.data;\n hasUpdated.current = true;\n }\n } else if (message.type === \"viewport-clear\") {\n onSizeChange?.(0);\n dataWindow.setRowCount(0);\n setData([]);\n\n if (isMounted.current === false) {\n console.log(\"setting state whilst unmounted\");\n }\n\n forceUpdate({});\n } else {\n console.log(`useDataSource unexpected message ${message.type}`);\n }\n },\n [autoSelect, dataWindow, onSizeChange, onSubscribed, selectRow, setData],\n );\n\n const getSelectedRows = useCallback(() => {\n return dataWindow.getSelectedRows();\n }, [dataWindow]);\n\n useEffect(() => {\n if (dataSource.status === \"disabled\") {\n dataSource.enable?.(datasourceMessageHandler);\n }\n }, [dataSource, datasourceMessageHandler]);\n\n const setRange = useCallback(\n (viewportRange: VuuRange) => {\n if (!rangeRef.current.equals(viewportRange)) {\n const range = Range(\n viewportRange.from,\n viewportRange.to,\n renderBufferSize,\n );\n\n dataWindow.setRange(range.withBuffer);\n\n if (\n dataSource.status !== \"subscribed\" &&\n dataSource.status !== \"subscribing\" &&\n dataSource.status !== \"enabling\"\n ) {\n dataSource?.subscribe(\n {\n range,\n revealSelected,\n selectedKeyValues: autoSelectRowKey\n ? [autoSelectRowKey]\n : undefined,\n },\n datasourceMessageHandler,\n );\n } else {\n dataSource.range = rangeRef.current = range;\n }\n }\n },\n [\n autoSelectRowKey,\n dataSource,\n dataWindow,\n datasourceMessageHandler,\n renderBufferSize,\n revealSelected,\n ],\n );\n\n useEffect(() => {\n isMounted.current = true;\n if (dataSource.status !== \"initialising\") {\n dataSource.resume?.(datasourceMessageHandler);\n\n if (dataSource.range.from > 0) {\n // UI does not currently restore scroll position, so always reset to top of dataset\n const { from, to } = rangeRef.current.reset;\n setRange({ from, to });\n }\n }\n return () => {\n isMounted.current = false;\n dataSource.suspend?.(\n suspenseProps?.escalateToDisable,\n suspenseProps?.escalateDelay,\n );\n };\n }, [dataSource, datasourceMessageHandler, setRange, suspenseProps]);\n\n const removeColumnDataFromCache = useCallback(\n (indexOfRemovedColumn: number) => {\n dataWindow.spliceDataAtIndex(indexOfRemovedColumn);\n data.current = dataWindow.data;\n },\n [dataWindow],\n );\n\n return {\n data: data.current,\n dataRef: data,\n getSelectedRows,\n range: rangeRef.current,\n removeColumnDataFromCache,\n setRange,\n };\n};\n"],"names":["metadataKeys","useState","useRef","useCallback","useEffect","useMemo","MovingWindow","row","Range"],"mappings":"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"}
@@ -44,6 +44,7 @@ const useCellFocus = ({
44
44
  }
45
45
  }
46
46
  state.cellPos = cellPos;
47
+ console.log(`[useCellFocus] requestScroll ${cellPos[0]}`);
47
48
  requestScroll?.({ type: "scroll-row", rowIndex: cellPos[0] });
48
49
  activeCell.focus({ preventScroll: true });
49
50
  }
@@ -1 +1 @@
1
- {"version":3,"file":"useCellFocus.js","sources":["../../../packages/vuu-table/src/useCellFocus.ts"],"sourcesContent":["import {\n KeyboardEventHandler,\n RefCallback,\n RefObject,\n useCallback,\n} from \"react\";\nimport {\n dataCellQuery,\n getTableCell,\n headerCellQuery,\n} from \"./table-dom-utils\";\nimport { ScrollRequestHandler } from \"./useTableScroll\";\nimport { isArrowKey, queryClosest } from \"@vuu-ui/vuu-utils\";\nimport { CellPos } from \"@vuu-ui/vuu-table-types\";\nimport type { ICellFocusState } from \"./CellFocusState\";\n\nexport interface CellFocusHookProps {\n cellFocusStateRef: RefObject<ICellFocusState>;\n containerRef: RefObject<HTMLElement | null>;\n disableFocus?: boolean;\n requestScroll?: ScrollRequestHandler;\n}\n\nconst getCellPosition = (el: HTMLElement) => {\n const top = parseInt(el.parentElement?.style.top ?? \"-1\");\n return { top };\n};\n\nconst isDifferentCellPosition = (\n currentPos: CellPos | undefined,\n newPos: CellPos,\n) => {\n if (currentPos === undefined) {\n return true;\n }\n return currentPos[0] !== newPos[0] || currentPos[1] !== newPos[1];\n};\n\nexport type FocusCell = (cellPos: CellPos, fromKeyboard?: boolean) => void;\n\nexport const useCellFocus = ({\n cellFocusStateRef,\n containerRef,\n disableFocus = false,\n requestScroll,\n}: CellFocusHookProps) => {\n const focusCellPlaceholderRef = useCallback<RefCallback<HTMLDivElement>>(\n (el) => {\n cellFocusStateRef.current.placeholderEl = el;\n },\n [cellFocusStateRef],\n );\n\n const focusCell = useCallback<FocusCell>(\n (cellPos) => {\n if (containerRef.current) {\n const { current: state } = cellFocusStateRef;\n if (isDifferentCellPosition(state.cellPos, cellPos)) {\n const activeCell = getTableCell(containerRef, cellPos);\n if (activeCell) {\n if (activeCell !== state.el) {\n state.el?.removeAttribute(\"tabindex\");\n activeCell.setAttribute(\"tabindex\", \"0\");\n\n // TODO no need to measure if we're navigating horizontally\n // state.cellPos = cellPos;\n state.el = activeCell;\n state.pos = getCellPosition(activeCell);\n state.outsideViewport = false;\n\n if (state.placeholderEl) {\n state.placeholderEl.style.top = `${state.pos.top}px`;\n }\n }\n state.cellPos = cellPos;\n\n // TODO needs to be scroll cell to accommodate horizontal virtualization\n requestScroll?.({ type: \"scroll-row\", rowIndex: cellPos[0] });\n activeCell.focus({ preventScroll: true });\n }\n }\n }\n },\n [cellFocusStateRef, containerRef, requestScroll],\n );\n\n const setTableBodyRef = useCallback<RefCallback<HTMLDivElement>>(\n (el) => {\n if (el) {\n const { current: state } = cellFocusStateRef;\n const table = queryClosest<HTMLDivElement>(el, \".vuuTable\");\n if (table) {\n if (state.el === null && !disableFocus) {\n const headerCell = table.querySelector<HTMLDivElement>(\n headerCellQuery(1),\n );\n if (headerCell) {\n headerCell.setAttribute(\"tabindex\", \"0\");\n state.cellPos = [1, 1];\n state.el = headerCell;\n state.pos = { top: -20 };\n if (state.placeholderEl) {\n state.placeholderEl.style.top = `-20px`;\n }\n } else {\n const cell = table.querySelector<HTMLDivElement>(\n dataCellQuery(0, 0),\n );\n if (cell) {\n cell.setAttribute(\"tabindex\", \"0\");\n state.cellPos = [1, 1];\n state.el = cell;\n state.pos = { top: 0 };\n if (state.placeholderEl) {\n state.placeholderEl.style.top = `0px`;\n }\n }\n }\n }\n }\n }\n },\n [cellFocusStateRef, disableFocus],\n );\n\n const focusCellPlaceholderKeyDown = useCallback<KeyboardEventHandler>(\n (evt) => {\n const { outsideViewport, pos } = cellFocusStateRef.current;\n if (pos && isArrowKey(evt.key)) {\n // TODO depends on whether we're scrolling up or down\n if (outsideViewport === \"above\") {\n requestScroll?.({ type: \"scroll-top\", scrollPos: pos.top });\n } else if (outsideViewport === \"below\") {\n requestScroll?.({ type: \"scroll-bottom\", scrollPos: pos.top });\n } else {\n throw Error(\n `cellFocusPlaceholder should not have focus if inside viewport`,\n );\n }\n }\n },\n [cellFocusStateRef, requestScroll],\n );\n\n return {\n focusCell,\n focusCellPlaceholderKeyDown,\n focusCellPlaceholderRef,\n setTableBodyRef,\n };\n};\n"],"names":["useCallback","getTableCell","queryClosest","headerCellQuery","dataCellQuery","isArrowKey"],"mappings":"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"}
1
+ {"version":3,"file":"useCellFocus.js","sources":["../../../packages/vuu-table/src/useCellFocus.ts"],"sourcesContent":["import {\n KeyboardEventHandler,\n RefCallback,\n RefObject,\n useCallback,\n} from \"react\";\nimport {\n dataCellQuery,\n getTableCell,\n headerCellQuery,\n} from \"./table-dom-utils\";\nimport { ScrollRequestHandler } from \"./useTableScroll\";\nimport { isArrowKey, queryClosest } from \"@vuu-ui/vuu-utils\";\nimport { CellPos } from \"@vuu-ui/vuu-table-types\";\nimport type { ICellFocusState } from \"./CellFocusState\";\n\nexport interface CellFocusHookProps {\n cellFocusStateRef: RefObject<ICellFocusState>;\n containerRef: RefObject<HTMLElement | null>;\n disableFocus?: boolean;\n requestScroll?: ScrollRequestHandler;\n}\n\nconst getCellPosition = (el: HTMLElement) => {\n const top = parseInt(el.parentElement?.style.top ?? \"-1\");\n return { top };\n};\n\nconst isDifferentCellPosition = (\n currentPos: CellPos | undefined,\n newPos: CellPos,\n) => {\n if (currentPos === undefined) {\n return true;\n }\n return currentPos[0] !== newPos[0] || currentPos[1] !== newPos[1];\n};\n\nexport type FocusCell = (cellPos: CellPos, fromKeyboard?: boolean) => void;\n\nexport const useCellFocus = ({\n cellFocusStateRef,\n containerRef,\n disableFocus = false,\n requestScroll,\n}: CellFocusHookProps) => {\n const focusCellPlaceholderRef = useCallback<RefCallback<HTMLDivElement>>(\n (el) => {\n cellFocusStateRef.current.placeholderEl = el;\n },\n [cellFocusStateRef],\n );\n\n const focusCell = useCallback<FocusCell>(\n (cellPos) => {\n if (containerRef.current) {\n const { current: state } = cellFocusStateRef;\n if (isDifferentCellPosition(state.cellPos, cellPos)) {\n const activeCell = getTableCell(containerRef, cellPos);\n if (activeCell) {\n if (activeCell !== state.el) {\n state.el?.removeAttribute(\"tabindex\");\n activeCell.setAttribute(\"tabindex\", \"0\");\n\n // TODO no need to measure if we're navigating horizontally\n // state.cellPos = cellPos;\n state.el = activeCell;\n state.pos = getCellPosition(activeCell);\n state.outsideViewport = false;\n\n if (state.placeholderEl) {\n state.placeholderEl.style.top = `${state.pos.top}px`;\n }\n }\n state.cellPos = cellPos;\n\n // TODO needs to be scroll cell to accommodate horizontal virtualization\n console.log(`[useCellFocus] requestScroll ${cellPos[0]}`);\n\n requestScroll?.({ type: \"scroll-row\", rowIndex: cellPos[0] });\n activeCell.focus({ preventScroll: true });\n }\n }\n }\n },\n [cellFocusStateRef, containerRef, requestScroll],\n );\n\n const setTableBodyRef = useCallback<RefCallback<HTMLDivElement>>(\n (el) => {\n if (el) {\n const { current: state } = cellFocusStateRef;\n const table = queryClosest<HTMLDivElement>(el, \".vuuTable\");\n if (table) {\n if (state.el === null && !disableFocus) {\n const headerCell = table.querySelector<HTMLDivElement>(\n headerCellQuery(1),\n );\n if (headerCell) {\n headerCell.setAttribute(\"tabindex\", \"0\");\n state.cellPos = [1, 1];\n state.el = headerCell;\n state.pos = { top: -20 };\n if (state.placeholderEl) {\n state.placeholderEl.style.top = `-20px`;\n }\n } else {\n const cell = table.querySelector<HTMLDivElement>(\n dataCellQuery(0, 0),\n );\n if (cell) {\n cell.setAttribute(\"tabindex\", \"0\");\n state.cellPos = [1, 1];\n state.el = cell;\n state.pos = { top: 0 };\n if (state.placeholderEl) {\n state.placeholderEl.style.top = `0px`;\n }\n }\n }\n }\n }\n }\n },\n [cellFocusStateRef, disableFocus],\n );\n\n const focusCellPlaceholderKeyDown = useCallback<KeyboardEventHandler>(\n (evt) => {\n const { outsideViewport, pos } = cellFocusStateRef.current;\n if (pos && isArrowKey(evt.key)) {\n // TODO depends on whether we're scrolling up or down\n if (outsideViewport === \"above\") {\n requestScroll?.({ type: \"scroll-top\", scrollPos: pos.top });\n } else if (outsideViewport === \"below\") {\n requestScroll?.({ type: \"scroll-bottom\", scrollPos: pos.top });\n } else {\n throw Error(\n `cellFocusPlaceholder should not have focus if inside viewport`,\n );\n }\n }\n },\n [cellFocusStateRef, requestScroll],\n );\n\n return {\n focusCell,\n focusCellPlaceholderKeyDown,\n focusCellPlaceholderRef,\n setTableBodyRef,\n };\n};\n"],"names":["useCallback","getTableCell","queryClosest","headerCellQuery","dataCellQuery","isArrowKey"],"mappings":"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"}
@@ -10,15 +10,7 @@ const getMaxScroll = (container) => {
10
10
  const { clientHeight, clientWidth, scrollHeight, scrollWidth } = container;
11
11
  return [scrollWidth - clientWidth, scrollHeight - clientHeight];
12
12
  };
13
- const getScrollDirection = (prevScrollPositions, scrollPos) => {
14
- if (prevScrollPositions === void 0) {
15
- return void 0;
16
- } else {
17
- const { scrollTop: prevTop } = prevScrollPositions;
18
- return scrollPos > prevTop ? "fwd" : "bwd";
19
- }
20
- };
21
- const getPctScroll = (container, currentScrollPos) => {
13
+ const getPctScroll = (container) => {
22
14
  const {
23
15
  clientHeight,
24
16
  clientWidth,
@@ -30,13 +22,7 @@ const getPctScroll = (container, currentScrollPos) => {
30
22
  const maxScrollLeft = scrollWidth - clientWidth;
31
23
  const pctScrollLeft = scrollLeft / (scrollWidth - clientWidth);
32
24
  const maxScrollTop = scrollHeight - clientHeight;
33
- let pctScrollTop = scrollTop / (scrollHeight - clientHeight);
34
- const scrollDirection = getScrollDirection(currentScrollPos, scrollTop);
35
- if (scrollDirection === "fwd" && pctScrollTop > 0.99) {
36
- pctScrollTop = 1;
37
- } else if (scrollDirection === "bwd" && pctScrollTop < 0.02) {
38
- pctScrollTop = 0;
39
- }
25
+ const pctScrollTop = scrollTop / (scrollHeight - clientHeight);
40
26
  return [
41
27
  scrollLeft,
42
28
  pctScrollLeft,
@@ -160,7 +146,6 @@ const useTableScroll = ({
160
146
  focusState.outsideViewport = row < firstRow ? "above" : "below";
161
147
  } else if (isInViewport && !wasInViewport) {
162
148
  focusState.outsideViewport = false;
163
- focusCell?.(focusState.cellPos);
164
149
  }
165
150
  }
166
151
  }
@@ -168,7 +153,7 @@ const useTableScroll = ({
168
153
  },
169
154
  [
170
155
  cellFocusStateRef,
171
- focusCell,
156
+ // focusCell,
172
157
  getRowAtPosition,
173
158
  onVerticalScroll,
174
159
  onVerticalScrollInSitu,
@@ -182,7 +167,7 @@ const useTableScroll = ({
182
167
  const { current: contentContainer } = contentContainerRef;
183
168
  const { current: scrollbarContainer } = scrollbarContainerRef;
184
169
  if (scrollbarContainer && contentContainer) {
185
- const [scrollLeft, pctScrollLeft, , scrollTop, pctScrollTop] = getPctScroll(scrollbarContainer, scrollPos);
170
+ const [scrollLeft, pctScrollLeft, , scrollTop, pctScrollTop] = getPctScroll(scrollbarContainer);
186
171
  if (scrollLeft !== scrollPos.scrollLeft || scrollTop !== scrollPos.scrollTop) {
187
172
  scrollbarContainerScrolledRef.current = true;
188
173
  scrollPos.scrollLeft = scrollLeft;
@@ -208,7 +193,7 @@ const useTableScroll = ({
208
193
  contentContainerScrolledRef.current = false;
209
194
  } else if (contentContainer && scrollbarContainer) {
210
195
  scrollbarContainerScrolledRef.current = true;
211
- const [scrollLeft, pctScrollLeft, , scrollTop, pctScrollTop] = getPctScroll(scrollbarContainer, scrollPos);
196
+ const [scrollLeft, pctScrollLeft, , scrollTop, pctScrollTop] = getPctScroll(scrollbarContainer);
212
197
  scrollPos.scrollLeft = scrollLeft;
213
198
  scrollPos.scrollTop = scrollTop;
214
199
  const [maxScrollLeft, maxScrollTop] = getMaxScroll(scrollbarContainer);
@@ -1 +1 @@
1
- {"version":3,"file":"useTableScroll.js","sources":["../../../packages/vuu-table/src/useTableScroll.ts"],"sourcesContent":["import {\n getColumnsInViewport,\n itemsChanged,\n RowAtPositionFunc,\n} from \"@vuu-ui/vuu-utils\";\nimport type { VuuRange } from \"@vuu-ui/vuu-protocol-types\";\nimport {\n ForwardedRef,\n RefObject,\n useCallback,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport type { ViewportMeasurements } from \"./useTableViewport\";\nimport {\n getRowElementByAriaIndex,\n howFarIsRowOutsideViewport,\n} from \"./table-dom-utils\";\nimport type { RuntimeColumnDescriptor } from \"@vuu-ui/vuu-table-types\";\nimport { FocusCell } from \"./useCellFocus\";\nimport { ICellFocusState } from \"./CellFocusState\";\n\nexport type ScrollDirectionVertical = \"up\" | \"down\";\nexport type ScrollDirectionHorizontal = \"left\" | \"right\";\nexport type ScrollDirection =\n | ScrollDirectionVertical\n | ScrollDirectionHorizontal;\n\n/**\n * scroll into view the row at given pixel offset.\n */\nexport interface ScrollRequestPosition {\n instant?: boolean;\n scrollPos: number;\n type: \"scroll-top\" | \"scroll-bottom\";\n}\n\n/**\n * scroll into view the row at given row index posiiton.\n */\nexport interface ScrollRequestRow {\n rowIndex: number;\n type: \"scroll-row\";\n}\nexport interface ScrollRequestEnd {\n type: \"scroll-end\";\n direction: \"home\" | \"end\";\n}\n\nexport interface ScrollRequestPage {\n type: \"scroll-page\";\n direction: ScrollDirectionVertical;\n}\n\nexport type ScrollRequest =\n | ScrollRequestPage\n | ScrollRequestEnd\n | ScrollRequestRow\n | ScrollRequestPosition;\n\nexport type ScrollRequestHandler = (request: ScrollRequest) => void;\n\nexport interface ScrollingAPI {\n scrollToIndex: (itemIndex: number) => void;\n scrollToKey: (rowKey: string) => void;\n}\n\n/** How far we allow horizontal scroll movement before we recheck the rendered columns */\nconst SCROLL_MOVE_CHECK_THRESHOLD = 100;\n\n/** The buffer size in pixels that we allow for rendering columns just outside the viewport */\nconst HORIZONTAL_SCROLL_BUFFER = 200;\n\n/**\n * Return the maximum scroll positions for gioven container\n * @param container\n * @returns [maxScrollLeft, maxScrollTop]\n */\nconst getMaxScroll = (container: HTMLElement) => {\n const { clientHeight, clientWidth, scrollHeight, scrollWidth } = container;\n return [scrollWidth - clientWidth, scrollHeight - clientHeight];\n};\n\nconst getScrollDirection = (\n prevScrollPositions: ScrollPos | undefined,\n scrollPos: number,\n) => {\n if (prevScrollPositions === undefined) {\n return undefined;\n } else {\n const { scrollTop: prevTop } = prevScrollPositions;\n return scrollPos > prevTop ? \"fwd\" : \"bwd\";\n }\n};\n\nconst getPctScroll = (container: HTMLElement, currentScrollPos?: ScrollPos) => {\n const {\n clientHeight,\n clientWidth,\n scrollHeight,\n scrollLeft,\n scrollTop,\n scrollWidth,\n } = container;\n\n const maxScrollLeft = scrollWidth - clientWidth;\n const pctScrollLeft = scrollLeft / (scrollWidth - clientWidth);\n const maxScrollTop = scrollHeight - clientHeight;\n let pctScrollTop = scrollTop / (scrollHeight - clientHeight);\n\n const scrollDirection = getScrollDirection(currentScrollPos, scrollTop);\n\n if (scrollDirection === \"fwd\" && pctScrollTop > 0.99) {\n pctScrollTop = 1;\n } else if (scrollDirection === \"bwd\" && pctScrollTop < 0.02) {\n pctScrollTop = 0;\n }\n\n return [\n scrollLeft,\n pctScrollLeft,\n maxScrollLeft,\n scrollTop,\n pctScrollTop,\n maxScrollTop,\n ];\n};\n\nexport const noScrolling: ScrollingAPI = {\n scrollToIndex: () => undefined,\n scrollToKey: () => undefined,\n};\n\ninterface CallbackRefHookProps<T = HTMLElement> {\n onAttach?: (el: T) => void;\n onDetach: (el: T) => void;\n label?: string;\n}\n\nconst useCallbackRef = <T = HTMLElement>({\n onAttach,\n onDetach,\n}: CallbackRefHookProps<T>) => {\n const ref = useRef<T | null>(null);\n const callbackRef = useCallback(\n (el: T | null) => {\n if (el) {\n ref.current = el;\n onAttach?.(el);\n } else if (ref.current) {\n const { current: originalRef } = ref;\n ref.current = el;\n onDetach?.(originalRef);\n }\n },\n [onAttach, onDetach],\n );\n return callbackRef;\n};\n\ntype ScrollPos = {\n scrollLeft: number;\n scrollTop: number;\n};\n\nexport interface TableScrollHookProps {\n cellFocusStateRef: RefObject<ICellFocusState>;\n columns: RuntimeColumnDescriptor[];\n focusCell?: FocusCell;\n getRowAtPosition: RowAtPositionFunc;\n onHorizontalScroll?: (scrollLeft: number) => void;\n onVerticalScroll?: (scrollTop: number, pctScrollTop: number) => void;\n /**\n * When we have a virtualized scroll container, keyboard navigation is\n * performed `in situ`. We shift the range of rows rendered within the\n * viewport, whithout actually moving the scroll position\n */\n onVerticalScrollInSitu?: (rowIndexOffsetCount: number) => void;\n rowHeight: number;\n scrollingApiRef?: ForwardedRef<ScrollingAPI>;\n setRange: (range: VuuRange) => void;\n showPaginationControls?: boolean;\n viewportMeasurements: ViewportMeasurements;\n}\n\nexport const useTableScroll = ({\n cellFocusStateRef,\n columns,\n focusCell,\n getRowAtPosition,\n onHorizontalScroll,\n onVerticalScroll,\n onVerticalScrollInSitu,\n rowHeight,\n scrollingApiRef,\n setRange,\n viewportMeasurements,\n}: TableScrollHookProps) => {\n const firstRowRef = useRef<number>(0);\n const rowHeightRef = useRef(rowHeight);\n const contentContainerScrolledRef = useRef(false);\n const contentContainerPosRef = useRef<ScrollPos>({\n scrollTop: 0,\n scrollLeft: 0,\n });\n const scrollbarContainerScrolledRef = useRef(false);\n const scrollbarContainerPosRef = useRef<ScrollPos>({\n scrollTop: 0,\n scrollLeft: 0,\n });\n const scrollbarContainerRef = useRef<HTMLDivElement | null>(null);\n const contentContainerRef = useRef<HTMLDivElement | null>(null);\n const lastHorizontalScrollCheckPoint = useRef(0);\n\n const {\n appliedPageSize,\n isVirtualScroll,\n rowCount: viewportRowCount,\n totalHeaderHeight,\n usesMeasuredHeaderHeight,\n viewportBodyHeight,\n viewportWidth,\n } = viewportMeasurements;\n\n const columnsWithinViewportRef = useRef<RuntimeColumnDescriptor[]>([]);\n const [, forceRefresh] = useState({});\n\n const preSpanRef = useRef(0);\n\n useMemo(() => {\n const [visibleColumns, offset] = getColumnsInViewport(\n columns,\n contentContainerPosRef.current.scrollLeft,\n contentContainerPosRef.current.scrollLeft +\n viewportWidth +\n HORIZONTAL_SCROLL_BUFFER,\n );\n preSpanRef.current = offset;\n columnsWithinViewportRef.current = visibleColumns;\n }, [viewportWidth, columns]);\n\n const handleHorizontalScroll = useCallback(\n (scrollLeft: number) => {\n contentContainerPosRef.current.scrollLeft = scrollLeft;\n onHorizontalScroll?.(scrollLeft);\n\n if (\n Math.abs(scrollLeft - lastHorizontalScrollCheckPoint.current) >\n SCROLL_MOVE_CHECK_THRESHOLD\n ) {\n lastHorizontalScrollCheckPoint.current = scrollLeft;\n\n const [visibleColumns, pre] = getColumnsInViewport(\n columns,\n scrollLeft,\n scrollLeft + viewportWidth + HORIZONTAL_SCROLL_BUFFER,\n );\n\n if (itemsChanged(columnsWithinViewportRef.current, visibleColumns)) {\n preSpanRef.current = pre;\n columnsWithinViewportRef.current = visibleColumns;\n forceRefresh({});\n }\n }\n },\n [columns, onHorizontalScroll, viewportWidth],\n );\n const handleVerticalScroll = useCallback(\n (scrollTop: number, pctScrollTop: number) => {\n contentContainerPosRef.current.scrollTop = scrollTop;\n const { current: prevFirstRow } = firstRowRef;\n\n onVerticalScroll?.(scrollTop, pctScrollTop);\n const firstRow = getRowAtPosition(scrollTop);\n if (firstRow !== prevFirstRow) {\n firstRowRef.current = firstRow;\n const lastRow = firstRow + viewportRowCount;\n setRange({ from: firstRow, to: lastRow });\n\n // If we've scrolled the focused cell out of view, we need to remove\n // focus from it. The row element will be recycled and used as the\n // render target for a different DataRow, we do not want the focus\n // state of the cell to be preserved.\n // Conversely, if we scroll the focussed cell back into the viewport,\n // we must re-apply focus to it. We use the placeholder cell for this.\n const { current: focusState } = cellFocusStateRef;\n if (focusState.cellPos) {\n const prevLastRow = prevFirstRow + viewportRowCount;\n const [row] = focusState.cellPos;\n const wasInViewport = row >= prevFirstRow && row < prevLastRow;\n const isInViewport = row >= firstRow && row < lastRow;\n\n if (wasInViewport && !isInViewport) {\n focusState.placeholderEl?.focus({ preventScroll: true });\n focusState.outsideViewport = row < firstRow ? \"above\" : \"below\";\n } else if (isInViewport && !wasInViewport) {\n focusState.outsideViewport = false;\n focusCell?.(focusState.cellPos);\n }\n }\n }\n onVerticalScrollInSitu?.(0);\n },\n [\n cellFocusStateRef,\n focusCell,\n getRowAtPosition,\n onVerticalScroll,\n onVerticalScrollInSitu,\n setRange,\n viewportRowCount,\n ],\n );\n\n // Because of the amount of work done when we rerender a virtualised section\n // we may drop scroll events. Make sure we get the final resting position right\n // by remeasuring after a short delay.\n const scrollTimerRef = useRef<ReturnType<typeof setTimeout>>(null);\n const checkScrollbarScrollPosition = useCallback(() => {\n const { current: scrollPos } = scrollbarContainerPosRef;\n const { current: contentContainer } = contentContainerRef;\n\n const { current: scrollbarContainer } = scrollbarContainerRef;\n\n if (scrollbarContainer && contentContainer) {\n const [scrollLeft, pctScrollLeft, , scrollTop, pctScrollTop] =\n getPctScroll(scrollbarContainer, scrollPos);\n\n if (\n scrollLeft !== scrollPos.scrollLeft ||\n scrollTop !== scrollPos.scrollTop\n ) {\n scrollbarContainerScrolledRef.current = true;\n\n scrollPos.scrollLeft = scrollLeft;\n scrollPos.scrollTop = scrollTop;\n\n const [maxScrollLeft, maxScrollTop] = getMaxScroll(scrollbarContainer);\n const contentScrollLeft = Math.round(pctScrollLeft * maxScrollLeft);\n const contentScrollTop = pctScrollTop * maxScrollTop;\n\n contentContainer.scrollTo({\n left: contentScrollLeft,\n top: contentScrollTop,\n behavior: \"auto\",\n });\n }\n\n scrollTimerRef.current = null;\n }\n }, []);\n\n const handleScrollbarContainerScroll = useCallback(() => {\n const { current: contentContainer } = contentContainerRef;\n const { current: scrollbarContainer } = scrollbarContainerRef;\n const { current: contentContainerScrolled } = contentContainerScrolledRef;\n const { current: scrollPos } = scrollbarContainerPosRef;\n\n if (contentContainerScrolled) {\n contentContainerScrolledRef.current = false;\n } else if (contentContainer && scrollbarContainer) {\n scrollbarContainerScrolledRef.current = true;\n const [scrollLeft, pctScrollLeft, , scrollTop, pctScrollTop] =\n getPctScroll(scrollbarContainer, scrollPos);\n\n scrollPos.scrollLeft = scrollLeft;\n scrollPos.scrollTop = scrollTop;\n\n const [maxScrollLeft, maxScrollTop] = getMaxScroll(scrollbarContainer);\n const contentScrollLeft = Math.round(pctScrollLeft * maxScrollLeft);\n const contentScrollTop = pctScrollTop * maxScrollTop;\n\n contentContainer.scrollTo({\n left: contentScrollLeft,\n top: contentScrollTop,\n behavior: \"auto\",\n });\n }\n\n if (scrollTimerRef.current) {\n clearTimeout(scrollTimerRef.current);\n }\n scrollTimerRef.current = setTimeout(checkScrollbarScrollPosition, 60);\n\n onVerticalScrollInSitu?.(0);\n }, [checkScrollbarScrollPosition, onVerticalScrollInSitu]);\n\n const handleContentContainerScroll = useCallback(() => {\n const { current: scrollbarContainerScrolled } =\n scrollbarContainerScrolledRef;\n const { current: contentContainer } = contentContainerRef;\n const { current: scrollbarContainer } = scrollbarContainerRef;\n const { current: scrollPos } = contentContainerPosRef;\n\n if (contentContainer && scrollbarContainer) {\n const [\n scrollLeft,\n pctScrollLeft,\n maxScrollLeft,\n scrollTop,\n pctScrollTop,\n maxScrollTop,\n ] = getPctScroll(contentContainer);\n\n contentContainerScrolledRef.current = true;\n\n if (scrollbarContainerScrolled) {\n scrollbarContainerScrolledRef.current = false;\n } else {\n scrollbarContainer.scrollLeft = Math.round(\n pctScrollLeft * maxScrollLeft,\n );\n scrollbarContainer.scrollTop = pctScrollTop * maxScrollTop;\n }\n\n if (scrollPos.scrollTop !== scrollTop) {\n handleVerticalScroll(scrollTop, pctScrollTop);\n }\n if (scrollPos.scrollLeft !== scrollLeft) {\n handleHorizontalScroll(scrollLeft);\n }\n }\n }, [handleVerticalScroll, handleHorizontalScroll]);\n\n const handleAttachScrollbarContainer = useCallback(\n (el: HTMLDivElement) => {\n scrollbarContainerRef.current = el;\n el.addEventListener(\"scroll\", handleScrollbarContainerScroll, {\n passive: true,\n });\n },\n [handleScrollbarContainerScroll],\n );\n\n const handleDetachScrollbarContainer = useCallback(\n (el: HTMLDivElement) => {\n scrollbarContainerRef.current = null;\n el.removeEventListener(\"scroll\", handleScrollbarContainerScroll);\n },\n [handleScrollbarContainerScroll],\n );\n\n const handleAttachContentContainer = useCallback(\n (el: HTMLDivElement) => {\n contentContainerRef.current = el;\n el.addEventListener(\"scroll\", handleContentContainerScroll, {\n passive: true,\n });\n },\n [handleContentContainerScroll],\n );\n\n const handleDetachContentContainer = useCallback(\n (el: HTMLDivElement) => {\n contentContainerRef.current = null;\n el.removeEventListener(\"scroll\", handleContentContainerScroll);\n },\n [handleContentContainerScroll],\n );\n\n const contentContainerCallbackRef = useCallbackRef({\n onAttach: handleAttachContentContainer,\n onDetach: handleDetachContentContainer,\n });\n\n const scrollbarContainerCallbackRef = useCallbackRef({\n onAttach: handleAttachScrollbarContainer,\n onDetach: handleDetachScrollbarContainer,\n });\n\n const requestScroll: ScrollRequestHandler = useCallback(\n (scrollRequest) => {\n const { current: contentContainer } = contentContainerRef;\n const { current: scrollbarContainer } = scrollbarContainerRef;\n\n if (contentContainer) {\n const [maxScrollLeft, maxScrollTop] = getMaxScroll(contentContainer);\n const { scrollLeft, scrollTop } = contentContainer;\n contentContainerScrolledRef.current = false;\n switch (scrollRequest.type) {\n case \"scroll-top\":\n {\n // special case for setting scroll position immediately back to top\n if (\n scrollRequest.instant &&\n scrollRequest.scrollPos === 0 &&\n scrollbarContainer\n ) {\n contentContainer.scrollTop = 0;\n scrollbarContainer.scrollTop = 0;\n } else {\n contentContainer.scrollTo({\n top: scrollRequest.scrollPos,\n left: scrollLeft,\n behavior: \"instant\",\n });\n }\n }\n break;\n case \"scroll-bottom\":\n {\n contentContainer.scrollTo({\n top:\n scrollRequest.scrollPos -\n (viewportBodyHeight - 2 * rowHeight),\n left: scrollLeft,\n behavior: \"instant\",\n });\n }\n break;\n case \"scroll-row\":\n {\n const activeRow = getRowElementByAriaIndex(\n contentContainer,\n scrollRequest.rowIndex,\n );\n\n if (activeRow !== null) {\n const [direction, distance] = howFarIsRowOutsideViewport(\n activeRow,\n totalHeaderHeight,\n );\n if (direction && distance) {\n if (isVirtualScroll) {\n const offset = direction === \"down\" ? 1 : -1;\n onVerticalScrollInSitu?.(offset);\n const firstRow = firstRowRef.current + offset;\n firstRowRef.current = firstRow;\n setRange({\n from: firstRow,\n to: firstRow + viewportRowCount,\n });\n } else {\n let newScrollLeft = scrollLeft;\n let newScrollTop = scrollTop;\n if (direction === \"up\" || direction === \"down\") {\n newScrollTop = Math.min(\n Math.max(0, scrollTop + distance),\n maxScrollTop,\n );\n } else {\n newScrollLeft = Math.min(\n Math.max(0, scrollLeft + distance),\n maxScrollLeft,\n );\n }\n contentContainer.scrollTo({\n top: newScrollTop,\n left: newScrollLeft,\n // avoid behaviour: 'smooth', doesn't work correctly\n behavior: \"instant\",\n });\n }\n }\n }\n }\n break;\n case \"scroll-page\":\n {\n const { direction } = scrollRequest;\n if (isVirtualScroll) {\n const offset =\n direction === \"down\" ? viewportRowCount : -viewportRowCount;\n onVerticalScrollInSitu?.(offset);\n const firstRow = firstRowRef.current + offset;\n firstRowRef.current = firstRow;\n setRange({ from: firstRow, to: firstRow + viewportRowCount });\n } else {\n const scrollBy =\n direction === \"down\" ? appliedPageSize : -appliedPageSize;\n const newScrollTop = Math.min(\n Math.max(0, scrollTop + scrollBy),\n maxScrollTop,\n );\n contentContainer.scrollTo({\n top: newScrollTop,\n left: scrollLeft,\n behavior: \"auto\",\n });\n }\n }\n break;\n case \"scroll-end\":\n {\n const { direction } = scrollRequest;\n const scrollTo = direction === \"end\" ? maxScrollTop : 0;\n contentContainer.scrollTo({\n top: scrollTo,\n left: contentContainer.scrollLeft,\n behavior: \"auto\",\n });\n }\n break;\n default:\n console.warn(`unexpected scroll request ${scrollRequest[\"type\"]}`);\n }\n }\n },\n [\n appliedPageSize,\n isVirtualScroll,\n onVerticalScrollInSitu,\n rowHeight,\n setRange,\n totalHeaderHeight,\n viewportBodyHeight,\n viewportRowCount,\n ],\n );\n\n const scrollHandles: ScrollingAPI = useMemo(\n // TODO not complete yet\n () => ({\n scrollToIndex: (rowIndex: number) => {\n if (scrollbarContainerRef.current) {\n // TODO hardcoded rowHeight\n const scrollPos = (rowIndex - 30) * 20;\n scrollbarContainerRef.current.scrollTop = scrollPos;\n }\n },\n scrollToKey: (rowKey: string) => {\n console.log(`scrollToKey ${rowKey}`);\n },\n }),\n [],\n );\n\n useImperativeHandle(scrollingApiRef, () => {\n if (scrollbarContainerRef.current) {\n return scrollHandles;\n } else {\n return noScrolling;\n }\n }, [scrollHandles]);\n\n useEffect(() => {\n if (rowHeight !== rowHeightRef.current) {\n rowHeightRef.current = rowHeight;\n if (contentContainerPosRef.current.scrollTop > 0) {\n if (contentContainerRef.current) {\n contentContainerRef.current.scrollTop = 0;\n }\n }\n } else if (usesMeasuredHeaderHeight) {\n const { current: from } = firstRowRef;\n const rowRange = { from, to: from + viewportRowCount };\n setRange(rowRange);\n }\n }, [rowHeight, setRange, usesMeasuredHeaderHeight, viewportRowCount]);\n\n return {\n columnsWithinViewport: columnsWithinViewportRef.current,\n /** Ref to be assigned to ScrollbarContainer */\n scrollbarContainerRef: scrollbarContainerCallbackRef,\n /** Ref to be assigned to ContentContainer */\n contentContainerRef: contentContainerCallbackRef,\n /** Scroll the table */\n requestScroll,\n scrollTop: contentContainerPosRef.current.scrollTop,\n /** number of leading columns not rendered because of virtualization */\n virtualColSpan: preSpanRef.current,\n };\n};\n"],"names":["useRef","useCallback","useState","useMemo","getColumnsInViewport","itemsChanged","getRowElementByAriaIndex","howFarIsRowOutsideViewport","useImperativeHandle","useEffect"],"mappings":";;;;;;AAuEA,MAAM,2BAA8B,GAAA,GAAA;AAGpC,MAAM,wBAA2B,GAAA,GAAA;AAOjC,MAAM,YAAA,GAAe,CAAC,SAA2B,KAAA;AAC/C,EAAA,MAAM,EAAE,YAAA,EAAc,WAAa,EAAA,YAAA,EAAc,aAAgB,GAAA,SAAA;AACjE,EAAA,OAAO,CAAC,WAAA,GAAc,WAAa,EAAA,YAAA,GAAe,YAAY,CAAA;AAChE,CAAA;AAEA,MAAM,kBAAA,GAAqB,CACzB,mBAAA,EACA,SACG,KAAA;AACH,EAAA,IAAI,wBAAwB,KAAW,CAAA,EAAA;AACrC,IAAO,OAAA,KAAA,CAAA;AAAA,GACF,MAAA;AACL,IAAM,MAAA,EAAE,SAAW,EAAA,OAAA,EAAY,GAAA,mBAAA;AAC/B,IAAO,OAAA,SAAA,GAAY,UAAU,KAAQ,GAAA,KAAA;AAAA;AAEzC,CAAA;AAEA,MAAM,YAAA,GAAe,CAAC,SAAA,EAAwB,gBAAiC,KAAA;AAC7E,EAAM,MAAA;AAAA,IACJ,YAAA;AAAA,IACA,WAAA;AAAA,IACA,YAAA;AAAA,IACA,UAAA;AAAA,IACA,SAAA;AAAA,IACA;AAAA,GACE,GAAA,SAAA;AAEJ,EAAA,MAAM,gBAAgB,WAAc,GAAA,WAAA;AACpC,EAAM,MAAA,aAAA,GAAgB,cAAc,WAAc,GAAA,WAAA,CAAA;AAClD,EAAA,MAAM,eAAe,YAAe,GAAA,YAAA;AACpC,EAAI,IAAA,YAAA,GAAe,aAAa,YAAe,GAAA,YAAA,CAAA;AAE/C,EAAM,MAAA,eAAA,GAAkB,kBAAmB,CAAA,gBAAA,EAAkB,SAAS,CAAA;AAEtE,EAAI,IAAA,eAAA,KAAoB,KAAS,IAAA,YAAA,GAAe,IAAM,EAAA;AACpD,IAAe,YAAA,GAAA,CAAA;AAAA,GACN,MAAA,IAAA,eAAA,KAAoB,KAAS,IAAA,YAAA,GAAe,IAAM,EAAA;AAC3D,IAAe,YAAA,GAAA,CAAA;AAAA;AAGjB,EAAO,OAAA;AAAA,IACL,UAAA;AAAA,IACA,aAAA;AAAA,IACA,aAAA;AAAA,IACA,SAAA;AAAA,IACA,YAAA;AAAA,IACA;AAAA,GACF;AACF,CAAA;AAEO,MAAM,WAA4B,GAAA;AAAA,EACvC,eAAe,MAAM,KAAA,CAAA;AAAA,EACrB,aAAa,MAAM,KAAA;AACrB;AAQA,MAAM,iBAAiB,CAAkB;AAAA,EACvC,QAAA;AAAA,EACA;AACF,CAA+B,KAAA;AAC7B,EAAM,MAAA,GAAA,GAAMA,aAAiB,IAAI,CAAA;AACjC,EAAA,MAAM,WAAc,GAAAC,iBAAA;AAAA,IAClB,CAAC,EAAiB,KAAA;AAChB,MAAA,IAAI,EAAI,EAAA;AACN,QAAA,GAAA,CAAI,OAAU,GAAA,EAAA;AACd,QAAA,QAAA,GAAW,EAAE,CAAA;AAAA,OACf,MAAA,IAAW,IAAI,OAAS,EAAA;AACtB,QAAM,MAAA,EAAE,OAAS,EAAA,WAAA,EAAgB,GAAA,GAAA;AACjC,QAAA,GAAA,CAAI,OAAU,GAAA,EAAA;AACd,QAAA,QAAA,GAAW,WAAW,CAAA;AAAA;AACxB,KACF;AAAA,IACA,CAAC,UAAU,QAAQ;AAAA,GACrB;AACA,EAAO,OAAA,WAAA;AACT,CAAA;AA2BO,MAAM,iBAAiB,CAAC;AAAA,EAC7B,iBAAA;AAAA,EACA,OAAA;AAAA,EACA,SAAA;AAAA,EACA,gBAAA;AAAA,EACA,kBAAA;AAAA,EACA,gBAAA;AAAA,EACA,sBAAA;AAAA,EACA,SAAA;AAAA,EACA,eAAA;AAAA,EACA,QAAA;AAAA,EACA;AACF,CAA4B,KAAA;AAC1B,EAAM,MAAA,WAAA,GAAcD,aAAe,CAAC,CAAA;AACpC,EAAM,MAAA,YAAA,GAAeA,aAAO,SAAS,CAAA;AACrC,EAAM,MAAA,2BAAA,GAA8BA,aAAO,KAAK,CAAA;AAChD,EAAA,MAAM,yBAAyBA,YAAkB,CAAA;AAAA,IAC/C,SAAW,EAAA,CAAA;AAAA,IACX,UAAY,EAAA;AAAA,GACb,CAAA;AACD,EAAM,MAAA,6BAAA,GAAgCA,aAAO,KAAK,CAAA;AAClD,EAAA,MAAM,2BAA2BA,YAAkB,CAAA;AAAA,IACjD,SAAW,EAAA,CAAA;AAAA,IACX,UAAY,EAAA;AAAA,GACb,CAAA;AACD,EAAM,MAAA,qBAAA,GAAwBA,aAA8B,IAAI,CAAA;AAChE,EAAM,MAAA,mBAAA,GAAsBA,aAA8B,IAAI,CAAA;AAC9D,EAAM,MAAA,8BAAA,GAAiCA,aAAO,CAAC,CAAA;AAE/C,EAAM,MAAA;AAAA,IACJ,eAAA;AAAA,IACA,eAAA;AAAA,IACA,QAAU,EAAA,gBAAA;AAAA,IACV,iBAAA;AAAA,IACA,wBAAA;AAAA,IACA,kBAAA;AAAA,IACA;AAAA,GACE,GAAA,oBAAA;AAEJ,EAAM,MAAA,wBAAA,GAA2BA,YAAkC,CAAA,EAAE,CAAA;AACrE,EAAA,MAAM,GAAG,YAAY,CAAI,GAAAE,cAAA,CAAS,EAAE,CAAA;AAEpC,EAAM,MAAA,UAAA,GAAaF,aAAO,CAAC,CAAA;AAE3B,EAAAG,aAAA,CAAQ,MAAM;AACZ,IAAM,MAAA,CAAC,cAAgB,EAAA,MAAM,CAAI,GAAAC,6BAAA;AAAA,MAC/B,OAAA;AAAA,MACA,uBAAuB,OAAQ,CAAA,UAAA;AAAA,MAC/B,sBAAA,CAAuB,OAAQ,CAAA,UAAA,GAC7B,aACA,GAAA;AAAA,KACJ;AACA,IAAA,UAAA,CAAW,OAAU,GAAA,MAAA;AACrB,IAAA,wBAAA,CAAyB,OAAU,GAAA,cAAA;AAAA,GAClC,EAAA,CAAC,aAAe,EAAA,OAAO,CAAC,CAAA;AAE3B,EAAA,MAAM,sBAAyB,GAAAH,iBAAA;AAAA,IAC7B,CAAC,UAAuB,KAAA;AACtB,MAAA,sBAAA,CAAuB,QAAQ,UAAa,GAAA,UAAA;AAC5C,MAAA,kBAAA,GAAqB,UAAU,CAAA;AAE/B,MAAA,IACE,KAAK,GAAI,CAAA,UAAA,GAAa,8BAA+B,CAAA,OAAO,IAC5D,2BACA,EAAA;AACA,QAAA,8BAAA,CAA+B,OAAU,GAAA,UAAA;AAEzC,QAAM,MAAA,CAAC,cAAgB,EAAA,GAAG,CAAI,GAAAG,6BAAA;AAAA,UAC5B,OAAA;AAAA,UACA,UAAA;AAAA,UACA,aAAa,aAAgB,GAAA;AAAA,SAC/B;AAEA,QAAA,IAAIC,qBAAa,CAAA,wBAAA,CAAyB,OAAS,EAAA,cAAc,CAAG,EAAA;AAClE,UAAA,UAAA,CAAW,OAAU,GAAA,GAAA;AACrB,UAAA,wBAAA,CAAyB,OAAU,GAAA,cAAA;AACnC,UAAA,YAAA,CAAa,EAAE,CAAA;AAAA;AACjB;AACF,KACF;AAAA,IACA,CAAC,OAAS,EAAA,kBAAA,EAAoB,aAAa;AAAA,GAC7C;AACA,EAAA,MAAM,oBAAuB,GAAAJ,iBAAA;AAAA,IAC3B,CAAC,WAAmB,YAAyB,KAAA;AAC3C,MAAA,sBAAA,CAAuB,QAAQ,SAAY,GAAA,SAAA;AAC3C,MAAM,MAAA,EAAE,OAAS,EAAA,YAAA,EAAiB,GAAA,WAAA;AAElC,MAAA,gBAAA,GAAmB,WAAW,YAAY,CAAA;AAC1C,MAAM,MAAA,QAAA,GAAW,iBAAiB,SAAS,CAAA;AAC3C,MAAA,IAAI,aAAa,YAAc,EAAA;AAC7B,QAAA,WAAA,CAAY,OAAU,GAAA,QAAA;AACtB,QAAA,MAAM,UAAU,QAAW,GAAA,gBAAA;AAC3B,QAAA,QAAA,CAAS,EAAE,IAAA,EAAM,QAAU,EAAA,EAAA,EAAI,SAAS,CAAA;AAQxC,QAAM,MAAA,EAAE,OAAS,EAAA,UAAA,EAAe,GAAA,iBAAA;AAChC,QAAA,IAAI,WAAW,OAAS,EAAA;AACtB,UAAA,MAAM,cAAc,YAAe,GAAA,gBAAA;AACnC,UAAM,MAAA,CAAC,GAAG,CAAA,GAAI,UAAW,CAAA,OAAA;AACzB,UAAM,MAAA,aAAA,GAAgB,GAAO,IAAA,YAAA,IAAgB,GAAM,GAAA,WAAA;AACnD,UAAM,MAAA,YAAA,GAAe,GAAO,IAAA,QAAA,IAAY,GAAM,GAAA,OAAA;AAE9C,UAAI,IAAA,aAAA,IAAiB,CAAC,YAAc,EAAA;AAClC,YAAA,UAAA,CAAW,aAAe,EAAA,KAAA,CAAM,EAAE,aAAA,EAAe,MAAM,CAAA;AACvD,YAAW,UAAA,CAAA,eAAA,GAAkB,GAAM,GAAA,QAAA,GAAW,OAAU,GAAA,OAAA;AAAA,WAC1D,MAAA,IAAW,YAAgB,IAAA,CAAC,aAAe,EAAA;AACzC,YAAA,UAAA,CAAW,eAAkB,GAAA,KAAA;AAC7B,YAAA,SAAA,GAAY,WAAW,OAAO,CAAA;AAAA;AAChC;AACF;AAEF,MAAA,sBAAA,GAAyB,CAAC,CAAA;AAAA,KAC5B;AAAA,IACA;AAAA,MACE,iBAAA;AAAA,MACA,SAAA;AAAA,MACA,gBAAA;AAAA,MACA,gBAAA;AAAA,MACA,sBAAA;AAAA,MACA,QAAA;AAAA,MACA;AAAA;AACF,GACF;AAKA,EAAM,MAAA,cAAA,GAAiBD,aAAsC,IAAI,CAAA;AACjE,EAAM,MAAA,4BAAA,GAA+BC,kBAAY,MAAM;AACrD,IAAM,MAAA,EAAE,OAAS,EAAA,SAAA,EAAc,GAAA,wBAAA;AAC/B,IAAM,MAAA,EAAE,OAAS,EAAA,gBAAA,EAAqB,GAAA,mBAAA;AAEtC,IAAM,MAAA,EAAE,OAAS,EAAA,kBAAA,EAAuB,GAAA,qBAAA;AAExC,IAAA,IAAI,sBAAsB,gBAAkB,EAAA;AAC1C,MAAM,MAAA,CAAC,YAAY,aAAe,IAAE,WAAW,YAAY,CAAA,GACzD,YAAa,CAAA,kBAAA,EAAoB,SAAS,CAAA;AAE5C,MAAA,IACE,UAAe,KAAA,SAAA,CAAU,UACzB,IAAA,SAAA,KAAc,UAAU,SACxB,EAAA;AACA,QAAA,6BAAA,CAA8B,OAAU,GAAA,IAAA;AAExC,QAAA,SAAA,CAAU,UAAa,GAAA,UAAA;AACvB,QAAA,SAAA,CAAU,SAAY,GAAA,SAAA;AAEtB,QAAA,MAAM,CAAC,aAAA,EAAe,YAAY,CAAA,GAAI,aAAa,kBAAkB,CAAA;AACrE,QAAA,MAAM,iBAAoB,GAAA,IAAA,CAAK,KAAM,CAAA,aAAA,GAAgB,aAAa,CAAA;AAClE,QAAA,MAAM,mBAAmB,YAAe,GAAA,YAAA;AAExC,QAAA,gBAAA,CAAiB,QAAS,CAAA;AAAA,UACxB,IAAM,EAAA,iBAAA;AAAA,UACN,GAAK,EAAA,gBAAA;AAAA,UACL,QAAU,EAAA;AAAA,SACX,CAAA;AAAA;AAGH,MAAA,cAAA,CAAe,OAAU,GAAA,IAAA;AAAA;AAC3B,GACF,EAAG,EAAE,CAAA;AAEL,EAAM,MAAA,8BAAA,GAAiCA,kBAAY,MAAM;AACvD,IAAM,MAAA,EAAE,OAAS,EAAA,gBAAA,EAAqB,GAAA,mBAAA;AACtC,IAAM,MAAA,EAAE,OAAS,EAAA,kBAAA,EAAuB,GAAA,qBAAA;AACxC,IAAM,MAAA,EAAE,OAAS,EAAA,wBAAA,EAA6B,GAAA,2BAAA;AAC9C,IAAM,MAAA,EAAE,OAAS,EAAA,SAAA,EAAc,GAAA,wBAAA;AAE/B,IAAA,IAAI,wBAA0B,EAAA;AAC5B,MAAA,2BAAA,CAA4B,OAAU,GAAA,KAAA;AAAA,KACxC,MAAA,IAAW,oBAAoB,kBAAoB,EAAA;AACjD,MAAA,6BAAA,CAA8B,OAAU,GAAA,IAAA;AACxC,MAAM,MAAA,CAAC,YAAY,aAAe,IAAE,WAAW,YAAY,CAAA,GACzD,YAAa,CAAA,kBAAA,EAAoB,SAAS,CAAA;AAE5C,MAAA,SAAA,CAAU,UAAa,GAAA,UAAA;AACvB,MAAA,SAAA,CAAU,SAAY,GAAA,SAAA;AAEtB,MAAA,MAAM,CAAC,aAAA,EAAe,YAAY,CAAA,GAAI,aAAa,kBAAkB,CAAA;AACrE,MAAA,MAAM,iBAAoB,GAAA,IAAA,CAAK,KAAM,CAAA,aAAA,GAAgB,aAAa,CAAA;AAClE,MAAA,MAAM,mBAAmB,YAAe,GAAA,YAAA;AAExC,MAAA,gBAAA,CAAiB,QAAS,CAAA;AAAA,QACxB,IAAM,EAAA,iBAAA;AAAA,QACN,GAAK,EAAA,gBAAA;AAAA,QACL,QAAU,EAAA;AAAA,OACX,CAAA;AAAA;AAGH,IAAA,IAAI,eAAe,OAAS,EAAA;AAC1B,MAAA,YAAA,CAAa,eAAe,OAAO,CAAA;AAAA;AAErC,IAAe,cAAA,CAAA,OAAA,GAAU,UAAW,CAAA,4BAAA,EAA8B,EAAE,CAAA;AAEpE,IAAA,sBAAA,GAAyB,CAAC,CAAA;AAAA,GACzB,EAAA,CAAC,4BAA8B,EAAA,sBAAsB,CAAC,CAAA;AAEzD,EAAM,MAAA,4BAAA,GAA+BA,kBAAY,MAAM;AACrD,IAAM,MAAA,EAAE,OAAS,EAAA,0BAAA,EACf,GAAA,6BAAA;AACF,IAAM,MAAA,EAAE,OAAS,EAAA,gBAAA,EAAqB,GAAA,mBAAA;AACtC,IAAM,MAAA,EAAE,OAAS,EAAA,kBAAA,EAAuB,GAAA,qBAAA;AACxC,IAAM,MAAA,EAAE,OAAS,EAAA,SAAA,EAAc,GAAA,sBAAA;AAE/B,IAAA,IAAI,oBAAoB,kBAAoB,EAAA;AAC1C,MAAM,MAAA;AAAA,QACJ,UAAA;AAAA,QACA,aAAA;AAAA,QACA,aAAA;AAAA,QACA,SAAA;AAAA,QACA,YAAA;AAAA,QACA;AAAA,OACF,GAAI,aAAa,gBAAgB,CAAA;AAEjC,MAAA,2BAAA,CAA4B,OAAU,GAAA,IAAA;AAEtC,MAAA,IAAI,0BAA4B,EAAA;AAC9B,QAAA,6BAAA,CAA8B,OAAU,GAAA,KAAA;AAAA,OACnC,MAAA;AACL,QAAA,kBAAA,CAAmB,aAAa,IAAK,CAAA,KAAA;AAAA,UACnC,aAAgB,GAAA;AAAA,SAClB;AACA,QAAA,kBAAA,CAAmB,YAAY,YAAe,GAAA,YAAA;AAAA;AAGhD,MAAI,IAAA,SAAA,CAAU,cAAc,SAAW,EAAA;AACrC,QAAA,oBAAA,CAAqB,WAAW,YAAY,CAAA;AAAA;AAE9C,MAAI,IAAA,SAAA,CAAU,eAAe,UAAY,EAAA;AACvC,QAAA,sBAAA,CAAuB,UAAU,CAAA;AAAA;AACnC;AACF,GACC,EAAA,CAAC,oBAAsB,EAAA,sBAAsB,CAAC,CAAA;AAEjD,EAAA,MAAM,8BAAiC,GAAAA,iBAAA;AAAA,IACrC,CAAC,EAAuB,KAAA;AACtB,MAAA,qBAAA,CAAsB,OAAU,GAAA,EAAA;AAChC,MAAG,EAAA,CAAA,gBAAA,CAAiB,UAAU,8BAAgC,EAAA;AAAA,QAC5D,OAAS,EAAA;AAAA,OACV,CAAA;AAAA,KACH;AAAA,IACA,CAAC,8BAA8B;AAAA,GACjC;AAEA,EAAA,MAAM,8BAAiC,GAAAA,iBAAA;AAAA,IACrC,CAAC,EAAuB,KAAA;AACtB,MAAA,qBAAA,CAAsB,OAAU,GAAA,IAAA;AAChC,MAAG,EAAA,CAAA,mBAAA,CAAoB,UAAU,8BAA8B,CAAA;AAAA,KACjE;AAAA,IACA,CAAC,8BAA8B;AAAA,GACjC;AAEA,EAAA,MAAM,4BAA+B,GAAAA,iBAAA;AAAA,IACnC,CAAC,EAAuB,KAAA;AACtB,MAAA,mBAAA,CAAoB,OAAU,GAAA,EAAA;AAC9B,MAAG,EAAA,CAAA,gBAAA,CAAiB,UAAU,4BAA8B,EAAA;AAAA,QAC1D,OAAS,EAAA;AAAA,OACV,CAAA;AAAA,KACH;AAAA,IACA,CAAC,4BAA4B;AAAA,GAC/B;AAEA,EAAA,MAAM,4BAA+B,GAAAA,iBAAA;AAAA,IACnC,CAAC,EAAuB,KAAA;AACtB,MAAA,mBAAA,CAAoB,OAAU,GAAA,IAAA;AAC9B,MAAG,EAAA,CAAA,mBAAA,CAAoB,UAAU,4BAA4B,CAAA;AAAA,KAC/D;AAAA,IACA,CAAC,4BAA4B;AAAA,GAC/B;AAEA,EAAA,MAAM,8BAA8B,cAAe,CAAA;AAAA,IACjD,QAAU,EAAA,4BAAA;AAAA,IACV,QAAU,EAAA;AAAA,GACX,CAAA;AAED,EAAA,MAAM,gCAAgC,cAAe,CAAA;AAAA,IACnD,QAAU,EAAA,8BAAA;AAAA,IACV,QAAU,EAAA;AAAA,GACX,CAAA;AAED,EAAA,MAAM,aAAsC,GAAAA,iBAAA;AAAA,IAC1C,CAAC,aAAkB,KAAA;AACjB,MAAM,MAAA,EAAE,OAAS,EAAA,gBAAA,EAAqB,GAAA,mBAAA;AACtC,MAAM,MAAA,EAAE,OAAS,EAAA,kBAAA,EAAuB,GAAA,qBAAA;AAExC,MAAA,IAAI,gBAAkB,EAAA;AACpB,QAAA,MAAM,CAAC,aAAA,EAAe,YAAY,CAAA,GAAI,aAAa,gBAAgB,CAAA;AACnE,QAAM,MAAA,EAAE,UAAY,EAAA,SAAA,EAAc,GAAA,gBAAA;AAClC,QAAA,2BAAA,CAA4B,OAAU,GAAA,KAAA;AACtC,QAAA,QAAQ,cAAc,IAAM;AAAA,UAC1B,KAAK,YAAA;AACH,YAAA;AAEE,cAAA,IACE,aAAc,CAAA,OAAA,IACd,aAAc,CAAA,SAAA,KAAc,KAC5B,kBACA,EAAA;AACA,gBAAA,gBAAA,CAAiB,SAAY,GAAA,CAAA;AAC7B,gBAAA,kBAAA,CAAmB,SAAY,GAAA,CAAA;AAAA,eAC1B,MAAA;AACL,gBAAA,gBAAA,CAAiB,QAAS,CAAA;AAAA,kBACxB,KAAK,aAAc,CAAA,SAAA;AAAA,kBACnB,IAAM,EAAA,UAAA;AAAA,kBACN,QAAU,EAAA;AAAA,iBACX,CAAA;AAAA;AACH;AAEF,YAAA;AAAA,UACF,KAAK,eAAA;AACH,YAAA;AACE,cAAA,gBAAA,CAAiB,QAAS,CAAA;AAAA,gBACxB,GACE,EAAA,aAAA,CAAc,SACb,IAAA,kBAAA,GAAqB,CAAI,GAAA,SAAA,CAAA;AAAA,gBAC5B,IAAM,EAAA,UAAA;AAAA,gBACN,QAAU,EAAA;AAAA,eACX,CAAA;AAAA;AAEH,YAAA;AAAA,UACF,KAAK,YAAA;AACH,YAAA;AACE,cAAA,MAAM,SAAY,GAAAK,sCAAA;AAAA,gBAChB,gBAAA;AAAA,gBACA,aAAc,CAAA;AAAA,eAChB;AAEA,cAAA,IAAI,cAAc,IAAM,EAAA;AACtB,gBAAM,MAAA,CAAC,SAAW,EAAA,QAAQ,CAAI,GAAAC,wCAAA;AAAA,kBAC5B,SAAA;AAAA,kBACA;AAAA,iBACF;AACA,gBAAA,IAAI,aAAa,QAAU,EAAA;AACzB,kBAAA,IAAI,eAAiB,EAAA;AACnB,oBAAM,MAAA,MAAA,GAAS,SAAc,KAAA,MAAA,GAAS,CAAI,GAAA,CAAA,CAAA;AAC1C,oBAAA,sBAAA,GAAyB,MAAM,CAAA;AAC/B,oBAAM,MAAA,QAAA,GAAW,YAAY,OAAU,GAAA,MAAA;AACvC,oBAAA,WAAA,CAAY,OAAU,GAAA,QAAA;AACtB,oBAAS,QAAA,CAAA;AAAA,sBACP,IAAM,EAAA,QAAA;AAAA,sBACN,IAAI,QAAW,GAAA;AAAA,qBAChB,CAAA;AAAA,mBACI,MAAA;AACL,oBAAA,IAAI,aAAgB,GAAA,UAAA;AACpB,oBAAA,IAAI,YAAe,GAAA,SAAA;AACnB,oBAAI,IAAA,SAAA,KAAc,IAAQ,IAAA,SAAA,KAAc,MAAQ,EAAA;AAC9C,sBAAA,YAAA,GAAe,IAAK,CAAA,GAAA;AAAA,wBAClB,IAAK,CAAA,GAAA,CAAI,CAAG,EAAA,SAAA,GAAY,QAAQ,CAAA;AAAA,wBAChC;AAAA,uBACF;AAAA,qBACK,MAAA;AACL,sBAAA,aAAA,GAAgB,IAAK,CAAA,GAAA;AAAA,wBACnB,IAAK,CAAA,GAAA,CAAI,CAAG,EAAA,UAAA,GAAa,QAAQ,CAAA;AAAA,wBACjC;AAAA,uBACF;AAAA;AAEF,oBAAA,gBAAA,CAAiB,QAAS,CAAA;AAAA,sBACxB,GAAK,EAAA,YAAA;AAAA,sBACL,IAAM,EAAA,aAAA;AAAA;AAAA,sBAEN,QAAU,EAAA;AAAA,qBACX,CAAA;AAAA;AACH;AACF;AACF;AAEF,YAAA;AAAA,UACF,KAAK,aAAA;AACH,YAAA;AACE,cAAM,MAAA,EAAE,WAAc,GAAA,aAAA;AACtB,cAAA,IAAI,eAAiB,EAAA;AACnB,gBAAA,MAAM,MACJ,GAAA,SAAA,KAAc,MAAS,GAAA,gBAAA,GAAmB,CAAC,gBAAA;AAC7C,gBAAA,sBAAA,GAAyB,MAAM,CAAA;AAC/B,gBAAM,MAAA,QAAA,GAAW,YAAY,OAAU,GAAA,MAAA;AACvC,gBAAA,WAAA,CAAY,OAAU,GAAA,QAAA;AACtB,gBAAA,QAAA,CAAS,EAAE,IAAM,EAAA,QAAA,EAAU,EAAI,EAAA,QAAA,GAAW,kBAAkB,CAAA;AAAA,eACvD,MAAA;AACL,gBAAA,MAAM,QACJ,GAAA,SAAA,KAAc,MAAS,GAAA,eAAA,GAAkB,CAAC,eAAA;AAC5C,gBAAA,MAAM,eAAe,IAAK,CAAA,GAAA;AAAA,kBACxB,IAAK,CAAA,GAAA,CAAI,CAAG,EAAA,SAAA,GAAY,QAAQ,CAAA;AAAA,kBAChC;AAAA,iBACF;AACA,gBAAA,gBAAA,CAAiB,QAAS,CAAA;AAAA,kBACxB,GAAK,EAAA,YAAA;AAAA,kBACL,IAAM,EAAA,UAAA;AAAA,kBACN,QAAU,EAAA;AAAA,iBACX,CAAA;AAAA;AACH;AAEF,YAAA;AAAA,UACF,KAAK,YAAA;AACH,YAAA;AACE,cAAM,MAAA,EAAE,WAAc,GAAA,aAAA;AACtB,cAAM,MAAA,QAAA,GAAW,SAAc,KAAA,KAAA,GAAQ,YAAe,GAAA,CAAA;AACtD,cAAA,gBAAA,CAAiB,QAAS,CAAA;AAAA,gBACxB,GAAK,EAAA,QAAA;AAAA,gBACL,MAAM,gBAAiB,CAAA,UAAA;AAAA,gBACvB,QAAU,EAAA;AAAA,eACX,CAAA;AAAA;AAEH,YAAA;AAAA,UACF;AACE,YAAA,OAAA,CAAQ,IAAK,CAAA,CAAA,0BAAA,EAA6B,aAAc,CAAA,MAAM,CAAC,CAAE,CAAA,CAAA;AAAA;AACrE;AACF,KACF;AAAA,IACA;AAAA,MACE,eAAA;AAAA,MACA,eAAA;AAAA,MACA,sBAAA;AAAA,MACA,SAAA;AAAA,MACA,QAAA;AAAA,MACA,iBAAA;AAAA,MACA,kBAAA;AAAA,MACA;AAAA;AACF,GACF;AAEA,EAAA,MAAM,aAA8B,GAAAJ,aAAA;AAAA;AAAA,IAElC,OAAO;AAAA,MACL,aAAA,EAAe,CAAC,QAAqB,KAAA;AACnC,QAAA,IAAI,sBAAsB,OAAS,EAAA;AAEjC,UAAM,MAAA,SAAA,GAAA,CAAa,WAAW,EAAM,IAAA,EAAA;AACpC,UAAA,qBAAA,CAAsB,QAAQ,SAAY,GAAA,SAAA;AAAA;AAC5C,OACF;AAAA,MACA,WAAA,EAAa,CAAC,MAAmB,KAAA;AAC/B,QAAQ,OAAA,CAAA,GAAA,CAAI,CAAe,YAAA,EAAA,MAAM,CAAE,CAAA,CAAA;AAAA;AACrC,KACF,CAAA;AAAA,IACA;AAAC,GACH;AAEA,EAAAK,yBAAA,CAAoB,iBAAiB,MAAM;AACzC,IAAA,IAAI,sBAAsB,OAAS,EAAA;AACjC,MAAO,OAAA,aAAA;AAAA,KACF,MAAA;AACL,MAAO,OAAA,WAAA;AAAA;AACT,GACF,EAAG,CAAC,aAAa,CAAC,CAAA;AAElB,EAAAC,eAAA,CAAU,MAAM;AACd,IAAI,IAAA,SAAA,KAAc,aAAa,OAAS,EAAA;AACtC,MAAA,YAAA,CAAa,OAAU,GAAA,SAAA;AACvB,MAAI,IAAA,sBAAA,CAAuB,OAAQ,CAAA,SAAA,GAAY,CAAG,EAAA;AAChD,QAAA,IAAI,oBAAoB,OAAS,EAAA;AAC/B,UAAA,mBAAA,CAAoB,QAAQ,SAAY,GAAA,CAAA;AAAA;AAC1C;AACF,eACS,wBAA0B,EAAA;AACnC,MAAM,MAAA,EAAE,OAAS,EAAA,IAAA,EAAS,GAAA,WAAA;AAC1B,MAAA,MAAM,QAAW,GAAA,EAAE,IAAM,EAAA,EAAA,EAAI,OAAO,gBAAiB,EAAA;AACrD,MAAA,QAAA,CAAS,QAAQ,CAAA;AAAA;AACnB,KACC,CAAC,SAAA,EAAW,QAAU,EAAA,wBAAA,EAA0B,gBAAgB,CAAC,CAAA;AAEpE,EAAO,OAAA;AAAA,IACL,uBAAuB,wBAAyB,CAAA,OAAA;AAAA;AAAA,IAEhD,qBAAuB,EAAA,6BAAA;AAAA;AAAA,IAEvB,mBAAqB,EAAA,2BAAA;AAAA;AAAA,IAErB,aAAA;AAAA,IACA,SAAA,EAAW,uBAAuB,OAAQ,CAAA,SAAA;AAAA;AAAA,IAE1C,gBAAgB,UAAW,CAAA;AAAA,GAC7B;AACF;;;;;"}
1
+ {"version":3,"file":"useTableScroll.js","sources":["../../../packages/vuu-table/src/useTableScroll.ts"],"sourcesContent":["import {\n getColumnsInViewport,\n itemsChanged,\n RowAtPositionFunc,\n} from \"@vuu-ui/vuu-utils\";\nimport type { VuuRange } from \"@vuu-ui/vuu-protocol-types\";\nimport {\n ForwardedRef,\n RefObject,\n useCallback,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport type { ViewportMeasurements } from \"./useTableViewport\";\nimport {\n getRowElementByAriaIndex,\n howFarIsRowOutsideViewport,\n} from \"./table-dom-utils\";\nimport type { RuntimeColumnDescriptor } from \"@vuu-ui/vuu-table-types\";\nimport { FocusCell } from \"./useCellFocus\";\nimport { ICellFocusState } from \"./CellFocusState\";\n\nexport type ScrollDirectionVertical = \"up\" | \"down\";\nexport type ScrollDirectionHorizontal = \"left\" | \"right\";\nexport type ScrollDirection =\n | ScrollDirectionVertical\n | ScrollDirectionHorizontal;\n\n/**\n * scroll into view the row at given pixel offset.\n */\nexport interface ScrollRequestPosition {\n instant?: boolean;\n scrollPos: number;\n type: \"scroll-top\" | \"scroll-bottom\";\n}\n\n/**\n * scroll into view the row at given row index posiiton.\n */\nexport interface ScrollRequestRow {\n rowIndex: number;\n type: \"scroll-row\";\n}\nexport interface ScrollRequestEnd {\n type: \"scroll-end\";\n direction: \"home\" | \"end\";\n}\n\nexport interface ScrollRequestPage {\n type: \"scroll-page\";\n direction: ScrollDirectionVertical;\n}\n\nexport type ScrollRequest =\n | ScrollRequestPage\n | ScrollRequestEnd\n | ScrollRequestRow\n | ScrollRequestPosition;\n\nexport type ScrollRequestHandler = (request: ScrollRequest) => void;\n\nexport interface ScrollingAPI {\n scrollToIndex: (itemIndex: number) => void;\n scrollToKey: (rowKey: string) => void;\n}\n\n/** How far we allow horizontal scroll movement before we recheck the rendered columns */\nconst SCROLL_MOVE_CHECK_THRESHOLD = 100;\n\n/** The buffer size in pixels that we allow for rendering columns just outside the viewport */\nconst HORIZONTAL_SCROLL_BUFFER = 200;\n\n/**\n * Return the maximum scroll positions for gioven container\n * @param container\n * @returns [maxScrollLeft, maxScrollTop]\n */\nconst getMaxScroll = (container: HTMLElement) => {\n const { clientHeight, clientWidth, scrollHeight, scrollWidth } = container;\n return [scrollWidth - clientWidth, scrollHeight - clientHeight];\n};\n\nconst getPctScroll = (container: HTMLElement) => {\n const {\n clientHeight,\n clientWidth,\n scrollHeight,\n scrollLeft,\n scrollTop,\n scrollWidth,\n } = container;\n\n const maxScrollLeft = scrollWidth - clientWidth;\n const pctScrollLeft = scrollLeft / (scrollWidth - clientWidth);\n const maxScrollTop = scrollHeight - clientHeight;\n const pctScrollTop = scrollTop / (scrollHeight - clientHeight);\n\n return [\n scrollLeft,\n pctScrollLeft,\n maxScrollLeft,\n scrollTop,\n pctScrollTop,\n maxScrollTop,\n ];\n};\n\nexport const noScrolling: ScrollingAPI = {\n scrollToIndex: () => undefined,\n scrollToKey: () => undefined,\n};\n\ninterface CallbackRefHookProps<T = HTMLElement> {\n onAttach?: (el: T) => void;\n onDetach: (el: T) => void;\n label?: string;\n}\n\nconst useCallbackRef = <T = HTMLElement>({\n onAttach,\n onDetach,\n}: CallbackRefHookProps<T>) => {\n const ref = useRef<T | null>(null);\n const callbackRef = useCallback(\n (el: T | null) => {\n if (el) {\n ref.current = el;\n onAttach?.(el);\n } else if (ref.current) {\n const { current: originalRef } = ref;\n ref.current = el;\n onDetach?.(originalRef);\n }\n },\n [onAttach, onDetach],\n );\n return callbackRef;\n};\n\ntype ScrollPos = {\n scrollLeft: number;\n scrollTop: number;\n};\n\nexport interface TableScrollHookProps {\n cellFocusStateRef: RefObject<ICellFocusState>;\n columns: RuntimeColumnDescriptor[];\n focusCell?: FocusCell;\n getRowAtPosition: RowAtPositionFunc;\n onHorizontalScroll?: (scrollLeft: number) => void;\n onVerticalScroll?: (scrollTop: number, pctScrollTop: number) => void;\n /**\n * When we have a virtualized scroll container, keyboard navigation is\n * performed `in situ`. We shift the range of rows rendered within the\n * viewport, whithout actually moving the scroll position\n */\n onVerticalScrollInSitu?: (rowIndexOffsetCount: number) => void;\n rowHeight: number;\n scrollingApiRef?: ForwardedRef<ScrollingAPI>;\n setRange: (range: VuuRange) => void;\n showPaginationControls?: boolean;\n viewportMeasurements: ViewportMeasurements;\n}\n\nexport const useTableScroll = ({\n cellFocusStateRef,\n columns,\n focusCell,\n getRowAtPosition,\n onHorizontalScroll,\n onVerticalScroll,\n onVerticalScrollInSitu,\n rowHeight,\n scrollingApiRef,\n setRange,\n viewportMeasurements,\n}: TableScrollHookProps) => {\n const firstRowRef = useRef<number>(0);\n const rowHeightRef = useRef(rowHeight);\n const contentContainerScrolledRef = useRef(false);\n const contentContainerPosRef = useRef<ScrollPos>({\n scrollTop: 0,\n scrollLeft: 0,\n });\n const scrollbarContainerScrolledRef = useRef(false);\n const scrollbarContainerPosRef = useRef<ScrollPos>({\n scrollTop: 0,\n scrollLeft: 0,\n });\n const scrollbarContainerRef = useRef<HTMLDivElement | null>(null);\n const contentContainerRef = useRef<HTMLDivElement | null>(null);\n const lastHorizontalScrollCheckPoint = useRef(0);\n\n const {\n appliedPageSize,\n isVirtualScroll,\n rowCount: viewportRowCount,\n totalHeaderHeight,\n usesMeasuredHeaderHeight,\n viewportBodyHeight,\n viewportWidth,\n } = viewportMeasurements;\n\n const columnsWithinViewportRef = useRef<RuntimeColumnDescriptor[]>([]);\n const [, forceRefresh] = useState({});\n\n const preSpanRef = useRef(0);\n\n useMemo(() => {\n const [visibleColumns, offset] = getColumnsInViewport(\n columns,\n contentContainerPosRef.current.scrollLeft,\n contentContainerPosRef.current.scrollLeft +\n viewportWidth +\n HORIZONTAL_SCROLL_BUFFER,\n );\n preSpanRef.current = offset;\n columnsWithinViewportRef.current = visibleColumns;\n }, [viewportWidth, columns]);\n\n const handleHorizontalScroll = useCallback(\n (scrollLeft: number) => {\n contentContainerPosRef.current.scrollLeft = scrollLeft;\n onHorizontalScroll?.(scrollLeft);\n\n if (\n Math.abs(scrollLeft - lastHorizontalScrollCheckPoint.current) >\n SCROLL_MOVE_CHECK_THRESHOLD\n ) {\n lastHorizontalScrollCheckPoint.current = scrollLeft;\n\n const [visibleColumns, pre] = getColumnsInViewport(\n columns,\n scrollLeft,\n scrollLeft + viewportWidth + HORIZONTAL_SCROLL_BUFFER,\n );\n\n if (itemsChanged(columnsWithinViewportRef.current, visibleColumns)) {\n preSpanRef.current = pre;\n columnsWithinViewportRef.current = visibleColumns;\n forceRefresh({});\n }\n }\n },\n [columns, onHorizontalScroll, viewportWidth],\n );\n const handleVerticalScroll = useCallback(\n (scrollTop: number, pctScrollTop: number) => {\n contentContainerPosRef.current.scrollTop = scrollTop;\n const { current: prevFirstRow } = firstRowRef;\n\n onVerticalScroll?.(scrollTop, pctScrollTop);\n const firstRow = getRowAtPosition(scrollTop);\n if (firstRow !== prevFirstRow) {\n firstRowRef.current = firstRow;\n const lastRow = firstRow + viewportRowCount;\n setRange({ from: firstRow, to: lastRow });\n\n // If we've scrolled the focused cell out of view, we need to remove\n // focus from it. The row element will be recycled and used as the\n // render target for a different DataRow, we do not want the focus\n // state of the cell to be preserved.\n // Conversely, if we scroll the focussed cell back into the viewport,\n // we must re-apply focus to it. We use the placeholder cell for this.\n const { current: focusState } = cellFocusStateRef;\n if (focusState.cellPos) {\n const prevLastRow = prevFirstRow + viewportRowCount;\n const [row] = focusState.cellPos;\n const wasInViewport = row >= prevFirstRow && row < prevLastRow;\n const isInViewport = row >= firstRow && row < lastRow;\n\n if (wasInViewport && !isInViewport) {\n focusState.placeholderEl?.focus({ preventScroll: true });\n focusState.outsideViewport = row < firstRow ? \"above\" : \"below\";\n } else if (isInViewport && !wasInViewport) {\n focusState.outsideViewport = false;\n // focusCell?.(focusState.cellPos);\n }\n }\n }\n onVerticalScrollInSitu?.(0);\n },\n [\n cellFocusStateRef,\n // focusCell,\n getRowAtPosition,\n onVerticalScroll,\n onVerticalScrollInSitu,\n setRange,\n viewportRowCount,\n ],\n );\n\n // Because of the amount of work done when we rerender a virtualised section\n // we may drop scroll events. Make sure we get the final resting position right\n // by remeasuring after a short delay.\n const scrollTimerRef = useRef<ReturnType<typeof setTimeout>>(null);\n const checkScrollbarScrollPosition = useCallback(() => {\n const { current: scrollPos } = scrollbarContainerPosRef;\n const { current: contentContainer } = contentContainerRef;\n\n const { current: scrollbarContainer } = scrollbarContainerRef;\n\n if (scrollbarContainer && contentContainer) {\n const [scrollLeft, pctScrollLeft, , scrollTop, pctScrollTop] =\n getPctScroll(scrollbarContainer);\n\n if (\n scrollLeft !== scrollPos.scrollLeft ||\n scrollTop !== scrollPos.scrollTop\n ) {\n scrollbarContainerScrolledRef.current = true;\n\n scrollPos.scrollLeft = scrollLeft;\n scrollPos.scrollTop = scrollTop;\n\n const [maxScrollLeft, maxScrollTop] = getMaxScroll(scrollbarContainer);\n const contentScrollLeft = Math.round(pctScrollLeft * maxScrollLeft);\n const contentScrollTop = pctScrollTop * maxScrollTop;\n\n contentContainer.scrollTo({\n left: contentScrollLeft,\n top: contentScrollTop,\n behavior: \"auto\",\n });\n }\n\n scrollTimerRef.current = null;\n }\n }, []);\n\n const handleScrollbarContainerScroll = useCallback(() => {\n const { current: contentContainer } = contentContainerRef;\n const { current: scrollbarContainer } = scrollbarContainerRef;\n const { current: contentContainerScrolled } = contentContainerScrolledRef;\n const { current: scrollPos } = scrollbarContainerPosRef;\n\n if (contentContainerScrolled) {\n contentContainerScrolledRef.current = false;\n } else if (contentContainer && scrollbarContainer) {\n scrollbarContainerScrolledRef.current = true;\n const [scrollLeft, pctScrollLeft, , scrollTop, pctScrollTop] =\n getPctScroll(scrollbarContainer);\n\n scrollPos.scrollLeft = scrollLeft;\n scrollPos.scrollTop = scrollTop;\n\n const [maxScrollLeft, maxScrollTop] = getMaxScroll(scrollbarContainer);\n const contentScrollLeft = Math.round(pctScrollLeft * maxScrollLeft);\n const contentScrollTop = pctScrollTop * maxScrollTop;\n\n contentContainer.scrollTo({\n left: contentScrollLeft,\n top: contentScrollTop,\n behavior: \"auto\",\n });\n }\n\n if (scrollTimerRef.current) {\n clearTimeout(scrollTimerRef.current);\n }\n scrollTimerRef.current = setTimeout(checkScrollbarScrollPosition, 60);\n\n onVerticalScrollInSitu?.(0);\n }, [checkScrollbarScrollPosition, onVerticalScrollInSitu]);\n\n const handleContentContainerScroll = useCallback(() => {\n const { current: scrollbarContainerScrolled } =\n scrollbarContainerScrolledRef;\n const { current: contentContainer } = contentContainerRef;\n const { current: scrollbarContainer } = scrollbarContainerRef;\n const { current: scrollPos } = contentContainerPosRef;\n\n if (contentContainer && scrollbarContainer) {\n const [\n scrollLeft,\n pctScrollLeft,\n maxScrollLeft,\n scrollTop,\n pctScrollTop,\n maxScrollTop,\n ] = getPctScroll(contentContainer);\n\n contentContainerScrolledRef.current = true;\n\n if (scrollbarContainerScrolled) {\n scrollbarContainerScrolledRef.current = false;\n } else {\n scrollbarContainer.scrollLeft = Math.round(\n pctScrollLeft * maxScrollLeft,\n );\n scrollbarContainer.scrollTop = pctScrollTop * maxScrollTop;\n }\n\n if (scrollPos.scrollTop !== scrollTop) {\n handleVerticalScroll(scrollTop, pctScrollTop);\n }\n if (scrollPos.scrollLeft !== scrollLeft) {\n handleHorizontalScroll(scrollLeft);\n }\n }\n }, [handleVerticalScroll, handleHorizontalScroll]);\n\n const handleAttachScrollbarContainer = useCallback(\n (el: HTMLDivElement) => {\n scrollbarContainerRef.current = el;\n el.addEventListener(\"scroll\", handleScrollbarContainerScroll, {\n passive: true,\n });\n },\n [handleScrollbarContainerScroll],\n );\n\n const handleDetachScrollbarContainer = useCallback(\n (el: HTMLDivElement) => {\n scrollbarContainerRef.current = null;\n el.removeEventListener(\"scroll\", handleScrollbarContainerScroll);\n },\n [handleScrollbarContainerScroll],\n );\n\n const handleAttachContentContainer = useCallback(\n (el: HTMLDivElement) => {\n contentContainerRef.current = el;\n el.addEventListener(\"scroll\", handleContentContainerScroll, {\n passive: true,\n });\n },\n [handleContentContainerScroll],\n );\n\n const handleDetachContentContainer = useCallback(\n (el: HTMLDivElement) => {\n contentContainerRef.current = null;\n el.removeEventListener(\"scroll\", handleContentContainerScroll);\n },\n [handleContentContainerScroll],\n );\n\n const contentContainerCallbackRef = useCallbackRef({\n onAttach: handleAttachContentContainer,\n onDetach: handleDetachContentContainer,\n });\n\n const scrollbarContainerCallbackRef = useCallbackRef({\n onAttach: handleAttachScrollbarContainer,\n onDetach: handleDetachScrollbarContainer,\n });\n\n const requestScroll: ScrollRequestHandler = useCallback(\n (scrollRequest) => {\n const { current: contentContainer } = contentContainerRef;\n const { current: scrollbarContainer } = scrollbarContainerRef;\n\n if (contentContainer) {\n const [maxScrollLeft, maxScrollTop] = getMaxScroll(contentContainer);\n const { scrollLeft, scrollTop } = contentContainer;\n contentContainerScrolledRef.current = false;\n switch (scrollRequest.type) {\n case \"scroll-top\":\n {\n // special case for setting scroll position immediately back to top\n if (\n scrollRequest.instant &&\n scrollRequest.scrollPos === 0 &&\n scrollbarContainer\n ) {\n contentContainer.scrollTop = 0;\n scrollbarContainer.scrollTop = 0;\n } else {\n contentContainer.scrollTo({\n top: scrollRequest.scrollPos,\n left: scrollLeft,\n behavior: \"instant\",\n });\n }\n }\n break;\n case \"scroll-bottom\":\n {\n contentContainer.scrollTo({\n top:\n scrollRequest.scrollPos -\n (viewportBodyHeight - 2 * rowHeight),\n left: scrollLeft,\n behavior: \"instant\",\n });\n }\n break;\n case \"scroll-row\":\n {\n const activeRow = getRowElementByAriaIndex(\n contentContainer,\n scrollRequest.rowIndex,\n );\n\n if (activeRow !== null) {\n const [direction, distance] = howFarIsRowOutsideViewport(\n activeRow,\n totalHeaderHeight,\n );\n if (direction && distance) {\n if (isVirtualScroll) {\n const offset = direction === \"down\" ? 1 : -1;\n onVerticalScrollInSitu?.(offset);\n const firstRow = firstRowRef.current + offset;\n firstRowRef.current = firstRow;\n setRange({\n from: firstRow,\n to: firstRow + viewportRowCount,\n });\n } else {\n let newScrollLeft = scrollLeft;\n let newScrollTop = scrollTop;\n if (direction === \"up\" || direction === \"down\") {\n newScrollTop = Math.min(\n Math.max(0, scrollTop + distance),\n maxScrollTop,\n );\n } else {\n newScrollLeft = Math.min(\n Math.max(0, scrollLeft + distance),\n maxScrollLeft,\n );\n }\n contentContainer.scrollTo({\n top: newScrollTop,\n left: newScrollLeft,\n // avoid behaviour: 'smooth', doesn't work correctly\n behavior: \"instant\",\n });\n }\n }\n }\n }\n break;\n case \"scroll-page\":\n {\n const { direction } = scrollRequest;\n if (isVirtualScroll) {\n const offset =\n direction === \"down\" ? viewportRowCount : -viewportRowCount;\n onVerticalScrollInSitu?.(offset);\n const firstRow = firstRowRef.current + offset;\n firstRowRef.current = firstRow;\n setRange({ from: firstRow, to: firstRow + viewportRowCount });\n } else {\n const scrollBy =\n direction === \"down\" ? appliedPageSize : -appliedPageSize;\n const newScrollTop = Math.min(\n Math.max(0, scrollTop + scrollBy),\n maxScrollTop,\n );\n contentContainer.scrollTo({\n top: newScrollTop,\n left: scrollLeft,\n behavior: \"auto\",\n });\n }\n }\n break;\n case \"scroll-end\":\n {\n const { direction } = scrollRequest;\n const scrollTo = direction === \"end\" ? maxScrollTop : 0;\n contentContainer.scrollTo({\n top: scrollTo,\n left: contentContainer.scrollLeft,\n behavior: \"auto\",\n });\n }\n break;\n default:\n console.warn(`unexpected scroll request ${scrollRequest[\"type\"]}`);\n }\n }\n },\n [\n appliedPageSize,\n isVirtualScroll,\n onVerticalScrollInSitu,\n rowHeight,\n setRange,\n totalHeaderHeight,\n viewportBodyHeight,\n viewportRowCount,\n ],\n );\n\n const scrollHandles: ScrollingAPI = useMemo(\n // TODO not complete yet\n () => ({\n scrollToIndex: (rowIndex: number) => {\n if (scrollbarContainerRef.current) {\n // TODO hardcoded rowHeight\n const scrollPos = (rowIndex - 30) * 20;\n scrollbarContainerRef.current.scrollTop = scrollPos;\n }\n },\n scrollToKey: (rowKey: string) => {\n console.log(`scrollToKey ${rowKey}`);\n },\n }),\n [],\n );\n\n useImperativeHandle(scrollingApiRef, () => {\n if (scrollbarContainerRef.current) {\n return scrollHandles;\n } else {\n return noScrolling;\n }\n }, [scrollHandles]);\n\n useEffect(() => {\n if (rowHeight !== rowHeightRef.current) {\n rowHeightRef.current = rowHeight;\n if (contentContainerPosRef.current.scrollTop > 0) {\n if (contentContainerRef.current) {\n contentContainerRef.current.scrollTop = 0;\n }\n }\n } else if (usesMeasuredHeaderHeight) {\n const { current: from } = firstRowRef;\n const rowRange = { from, to: from + viewportRowCount };\n setRange(rowRange);\n }\n }, [rowHeight, setRange, usesMeasuredHeaderHeight, viewportRowCount]);\n\n return {\n columnsWithinViewport: columnsWithinViewportRef.current,\n /** Ref to be assigned to ScrollbarContainer */\n scrollbarContainerRef: scrollbarContainerCallbackRef,\n /** Ref to be assigned to ContentContainer */\n contentContainerRef: contentContainerCallbackRef,\n /** Scroll the table */\n requestScroll,\n scrollTop: contentContainerPosRef.current.scrollTop,\n /** number of leading columns not rendered because of virtualization */\n virtualColSpan: preSpanRef.current,\n };\n};\n"],"names":["useRef","useCallback","useState","useMemo","getColumnsInViewport","itemsChanged","getRowElementByAriaIndex","howFarIsRowOutsideViewport","useImperativeHandle","useEffect"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { NULL_RANGE, Range, metadataKeys } from '@vuu-ui/vuu-utils';
1
+ import { Range, metadataKeys } from '@vuu-ui/vuu-utils';
2
2
  import { useState, useRef, useCallback, useEffect, useMemo } from 'react';
3
3
  import { MovingWindow } from './moving-window.js';
4
4
 
@@ -19,7 +19,7 @@ const useDataSource = ({
19
19
  const data = useRef([]);
20
20
  const isMounted = useRef(true);
21
21
  const hasUpdated = useRef(false);
22
- const rangeRef = useRef(NULL_RANGE);
22
+ const rangeRef = useRef(dataSource.range);
23
23
  const totalRowCountRef = useRef(0);
24
24
  const rowAutoSelected = useRef(false);
25
25
  const autoSelect = autoSelectRowKey ?? (autoSelectFirstRow || selectionModel === "single-no-deselect");
@@ -41,15 +41,10 @@ const useDataSource = ({
41
41
  }
42
42
  };
43
43
  }, [autoSelect, dataSource, handleConfigChange]);
44
- const dataWindow = useMemo(() => new MovingWindow(NULL_RANGE), []);
45
- useMemo(() => {
46
- dataSource.on("resumed", () => {
47
- const { range } = dataSource;
48
- if (range.to !== 0) {
49
- dataWindow.setRange(dataSource.range.withBuffer);
50
- }
51
- });
52
- }, [dataSource, dataWindow]);
44
+ const dataWindow = useMemo(
45
+ () => new MovingWindow(rangeRef.current.withBuffer),
46
+ []
47
+ );
53
48
  const setData = useCallback(
54
49
  (updates) => {
55
50
  for (const row of updates) {
@@ -131,19 +126,6 @@ const useDataSource = ({
131
126
  const getSelectedRows = useCallback(() => {
132
127
  return dataWindow.getSelectedRows();
133
128
  }, [dataWindow]);
134
- useEffect(() => {
135
- isMounted.current = true;
136
- if (dataSource.status !== "initialising") {
137
- dataSource.resume?.(datasourceMessageHandler);
138
- }
139
- return () => {
140
- isMounted.current = false;
141
- dataSource.suspend?.(
142
- suspenseProps?.escalateToDisable,
143
- suspenseProps?.escalateDelay
144
- );
145
- };
146
- }, [dataSource, datasourceMessageHandler, suspenseProps]);
147
129
  useEffect(() => {
148
130
  if (dataSource.status === "disabled") {
149
131
  dataSource.enable?.(datasourceMessageHandler);
@@ -158,7 +140,7 @@ const useDataSource = ({
158
140
  renderBufferSize
159
141
  );
160
142
  dataWindow.setRange(range.withBuffer);
161
- if (dataSource.status !== "subscribed" && dataSource.status !== "subscribing") {
143
+ if (dataSource.status !== "subscribed" && dataSource.status !== "subscribing" && dataSource.status !== "enabling") {
162
144
  dataSource?.subscribe(
163
145
  {
164
146
  range,
@@ -181,6 +163,23 @@ const useDataSource = ({
181
163
  revealSelected
182
164
  ]
183
165
  );
166
+ useEffect(() => {
167
+ isMounted.current = true;
168
+ if (dataSource.status !== "initialising") {
169
+ dataSource.resume?.(datasourceMessageHandler);
170
+ if (dataSource.range.from > 0) {
171
+ const { from, to } = rangeRef.current.reset;
172
+ setRange({ from, to });
173
+ }
174
+ }
175
+ return () => {
176
+ isMounted.current = false;
177
+ dataSource.suspend?.(
178
+ suspenseProps?.escalateToDisable,
179
+ suspenseProps?.escalateDelay
180
+ );
181
+ };
182
+ }, [dataSource, datasourceMessageHandler, setRange, suspenseProps]);
184
183
  const removeColumnDataFromCache = useCallback(
185
184
  (indexOfRemovedColumn) => {
186
185
  dataWindow.spliceDataAtIndex(indexOfRemovedColumn);
@@ -1 +1 @@
1
- {"version":3,"file":"useDataSource.js","sources":["../../../../packages/vuu-table/src/table-data-source/useDataSource.ts"],"sourcesContent":["import type {\n DataSourceConfigChangeHandler,\n DataSourceRow,\n DataSourceSubscribeCallback,\n DataSourceSubscribedMessage,\n DataSourceSuspenseProps,\n} from \"@vuu-ui/vuu-data-types\";\nimport { SelectRowRequest, VuuRange } from \"@vuu-ui/vuu-protocol-types\";\nimport { NULL_RANGE, Range } from \"@vuu-ui/vuu-utils\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { TableProps } from \"../Table\";\nimport { metadataKeys } from \"@vuu-ui/vuu-utils\";\nimport { TableRowSelectHandlerInternal } from \"@vuu-ui/vuu-table-types\";\nimport { MovingWindow } from \"./moving-window\";\n\nconst { KEY } = metadataKeys;\n\nexport interface DataSourceHookProps\n extends Pick<\n TableProps,\n | \"autoSelectFirstRow\"\n | \"autoSelectRowKey\"\n | \"dataSource\"\n | \"renderBufferSize\"\n | \"revealSelected\"\n | \"selectionModel\"\n > {\n suspenseProps?: DataSourceSuspenseProps;\n onSelect: TableRowSelectHandlerInternal;\n onSizeChange: (size: number) => void;\n onSubscribed: (subscription: DataSourceSubscribedMessage) => void;\n}\n\nexport const useDataSource = ({\n autoSelectFirstRow,\n autoSelectRowKey,\n dataSource,\n onSizeChange,\n onSubscribed,\n renderBufferSize = 0,\n revealSelected,\n onSelect,\n selectionModel,\n suspenseProps,\n}: DataSourceHookProps) => {\n const [, forceUpdate] = useState<unknown>(null);\n const data = useRef<DataSourceRow[]>([]);\n const isMounted = useRef(true);\n const hasUpdated = useRef(false);\n const rangeRef = useRef<Range>(NULL_RANGE);\n const totalRowCountRef = useRef(0);\n const rowAutoSelected = useRef(false);\n\n const autoSelect =\n autoSelectRowKey ??\n (autoSelectFirstRow || selectionModel === \"single-no-deselect\");\n\n const handleConfigChange = useCallback<DataSourceConfigChangeHandler>(\n (_config, _range, _confirmed, configChanges) => {\n if (configChanges?.filterChanged) {\n rowAutoSelected.current = false;\n }\n },\n [],\n );\n\n useEffect(() => {\n if (autoSelect) {\n dataSource.on(\"config\", handleConfigChange);\n }\n return () => {\n if (autoSelect) {\n dataSource.removeListener(\"config\", handleConfigChange);\n }\n };\n }, [autoSelect, dataSource, handleConfigChange]);\n\n const dataWindow = useMemo(() => new MovingWindow(NULL_RANGE), []);\n\n useMemo(() => {\n dataSource.on(\"resumed\", () => {\n // When we resume a dataSource (after switching tabs etc)\n // client will receive rows. We may not have received any\n // setRange calls at this point so dataWindow range will\n //not yet be set. If the dataWindow range is already set,\n // this is a no-op.\n const { range } = dataSource;\n if (range.to !== 0) {\n dataWindow.setRange(dataSource.range.withBuffer);\n }\n });\n }, [dataSource, dataWindow]);\n\n const setData = useCallback(\n (updates: DataSourceRow[]) => {\n for (const row of updates) {\n dataWindow.add(row);\n }\n data.current = dataWindow.data;\n if (isMounted.current) {\n // TODO do we ever need to worry about missing updates here ?\n forceUpdate({});\n }\n },\n [dataWindow],\n );\n\n const selectRow = useCallback(\n (row: DataSourceRow) => {\n const rowKey = row[KEY];\n dataSource.select?.({\n preserveExistingSelection: false,\n rowKey,\n type: \"SELECT_ROW\",\n } as SelectRowRequest);\n onSelect?.(row);\n },\n [dataSource, onSelect],\n );\n\n const datasourceMessageHandler: DataSourceSubscribeCallback = useCallback(\n (message) => {\n if (message.type === \"subscribed\") {\n onSubscribed?.(message);\n } else if (message.type === \"viewport-update\") {\n if (typeof message.size === \"number\") {\n onSizeChange?.(message.size);\n const size = dataWindow.data.length;\n dataWindow.setRowCount(message.size);\n totalRowCountRef.current = message.size;\n\n if (dataWindow.data.length < size) {\n if (isMounted.current === false) {\n console.log(\"setting state whilst unmounted\");\n }\n\n forceUpdate({});\n }\n }\n if (message.rows) {\n setData(message.rows);\n if (autoSelect && rowAutoSelected.current === false) {\n // OR if no selected row in message.rows, e.g after a filter\n rowAutoSelected.current = true;\n if (typeof autoSelect === \"string\") {\n const row = message.rows.find((row) => row[KEY] === autoSelect);\n if (row) {\n selectRow(row);\n } else {\n console.warn(\n `[useDataSource] autoSelect row key ${autoSelect} not in viewport`,\n );\n }\n } else if (message.rows.length > 0) {\n selectRow(message.rows[0]);\n }\n }\n } else if (message.size === 0) {\n setData([]);\n } else if (typeof message.size === \"number\") {\n data.current = dataWindow.data;\n hasUpdated.current = true;\n }\n } else if (message.type === \"viewport-clear\") {\n onSizeChange?.(0);\n dataWindow.setRowCount(0);\n setData([]);\n\n if (isMounted.current === false) {\n console.log(\"setting state whilst unmounted\");\n }\n\n forceUpdate({});\n } else {\n console.log(`useDataSource unexpected message ${message.type}`);\n }\n },\n [autoSelect, dataWindow, onSizeChange, onSubscribed, selectRow, setData],\n );\n\n const getSelectedRows = useCallback(() => {\n return dataWindow.getSelectedRows();\n }, [dataWindow]);\n\n useEffect(() => {\n isMounted.current = true;\n if (dataSource.status !== \"initialising\") {\n dataSource.resume?.(datasourceMessageHandler);\n }\n return () => {\n isMounted.current = false;\n dataSource.suspend?.(\n suspenseProps?.escalateToDisable,\n suspenseProps?.escalateDelay,\n );\n };\n }, [dataSource, datasourceMessageHandler, suspenseProps]);\n\n useEffect(() => {\n if (dataSource.status === \"disabled\") {\n dataSource.enable?.(datasourceMessageHandler);\n }\n }, [dataSource, datasourceMessageHandler]);\n\n const setRange = useCallback(\n (viewportRange: VuuRange) => {\n if (!rangeRef.current.equals(viewportRange)) {\n const range = Range(\n viewportRange.from,\n viewportRange.to,\n renderBufferSize,\n );\n\n dataWindow.setRange(range.withBuffer);\n\n if (\n dataSource.status !== \"subscribed\" &&\n dataSource.status !== \"subscribing\"\n ) {\n dataSource?.subscribe(\n {\n range,\n revealSelected,\n selectedKeyValues: autoSelectRowKey\n ? [autoSelectRowKey]\n : undefined,\n },\n datasourceMessageHandler,\n );\n } else {\n dataSource.range = rangeRef.current = range;\n }\n }\n },\n [\n autoSelectRowKey,\n dataSource,\n dataWindow,\n datasourceMessageHandler,\n renderBufferSize,\n revealSelected,\n ],\n );\n\n const removeColumnDataFromCache = useCallback(\n (indexOfRemovedColumn: number) => {\n dataWindow.spliceDataAtIndex(indexOfRemovedColumn);\n data.current = dataWindow.data;\n },\n [dataWindow],\n );\n\n return {\n data: data.current,\n dataRef: data,\n getSelectedRows,\n range: rangeRef.current,\n removeColumnDataFromCache,\n setRange,\n };\n};\n"],"names":["row"],"mappings":"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"}
1
+ {"version":3,"file":"useDataSource.js","sources":["../../../../packages/vuu-table/src/table-data-source/useDataSource.ts"],"sourcesContent":["import type {\n DataSourceConfigChangeHandler,\n DataSourceRow,\n DataSourceSubscribeCallback,\n DataSourceSubscribedMessage,\n DataSourceSuspenseProps,\n} from \"@vuu-ui/vuu-data-types\";\nimport { SelectRowRequest, VuuRange } from \"@vuu-ui/vuu-protocol-types\";\nimport { Range } from \"@vuu-ui/vuu-utils\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { TableProps } from \"../Table\";\nimport { metadataKeys } from \"@vuu-ui/vuu-utils\";\nimport { TableRowSelectHandlerInternal } from \"@vuu-ui/vuu-table-types\";\nimport { MovingWindow } from \"./moving-window\";\n\nconst { KEY } = metadataKeys;\n\nexport interface DataSourceHookProps\n extends Pick<\n TableProps,\n | \"autoSelectFirstRow\"\n | \"autoSelectRowKey\"\n | \"dataSource\"\n | \"renderBufferSize\"\n | \"revealSelected\"\n | \"selectionModel\"\n > {\n suspenseProps?: DataSourceSuspenseProps;\n onSelect: TableRowSelectHandlerInternal;\n onSizeChange: (size: number) => void;\n onSubscribed: (subscription: DataSourceSubscribedMessage) => void;\n}\n\nexport const useDataSource = ({\n autoSelectFirstRow,\n autoSelectRowKey,\n dataSource,\n onSizeChange,\n onSubscribed,\n renderBufferSize = 0,\n revealSelected,\n onSelect,\n selectionModel,\n suspenseProps,\n}: DataSourceHookProps) => {\n const [, forceUpdate] = useState<unknown>(null);\n const data = useRef<DataSourceRow[]>([]);\n const isMounted = useRef(true);\n const hasUpdated = useRef(false);\n const rangeRef = useRef<Range>(dataSource.range);\n const totalRowCountRef = useRef(0);\n const rowAutoSelected = useRef(false);\n\n const autoSelect =\n autoSelectRowKey ??\n (autoSelectFirstRow || selectionModel === \"single-no-deselect\");\n\n const handleConfigChange = useCallback<DataSourceConfigChangeHandler>(\n (_config, _range, _confirmed, configChanges) => {\n if (configChanges?.filterChanged) {\n rowAutoSelected.current = false;\n }\n },\n [],\n );\n\n useEffect(() => {\n if (autoSelect) {\n dataSource.on(\"config\", handleConfigChange);\n }\n return () => {\n if (autoSelect) {\n dataSource.removeListener(\"config\", handleConfigChange);\n }\n };\n }, [autoSelect, dataSource, handleConfigChange]);\n\n const dataWindow = useMemo(\n () => new MovingWindow(rangeRef.current.withBuffer),\n [],\n );\n\n const setData = useCallback(\n (updates: DataSourceRow[]) => {\n for (const row of updates) {\n dataWindow.add(row);\n }\n data.current = dataWindow.data;\n if (isMounted.current) {\n // TODO do we ever need to worry about missing updates here ?\n forceUpdate({});\n }\n },\n [dataWindow],\n );\n\n const selectRow = useCallback(\n (row: DataSourceRow) => {\n const rowKey = row[KEY];\n dataSource.select?.({\n preserveExistingSelection: false,\n rowKey,\n type: \"SELECT_ROW\",\n } as SelectRowRequest);\n onSelect?.(row);\n },\n [dataSource, onSelect],\n );\n\n const datasourceMessageHandler: DataSourceSubscribeCallback = useCallback(\n (message) => {\n if (message.type === \"subscribed\") {\n onSubscribed?.(message);\n } else if (message.type === \"viewport-update\") {\n if (typeof message.size === \"number\") {\n onSizeChange?.(message.size);\n const size = dataWindow.data.length;\n dataWindow.setRowCount(message.size);\n totalRowCountRef.current = message.size;\n\n if (dataWindow.data.length < size) {\n if (isMounted.current === false) {\n console.log(\"setting state whilst unmounted\");\n }\n\n forceUpdate({});\n }\n }\n if (message.rows) {\n setData(message.rows);\n if (autoSelect && rowAutoSelected.current === false) {\n // OR if no selected row in message.rows, e.g after a filter\n rowAutoSelected.current = true;\n if (typeof autoSelect === \"string\") {\n const row = message.rows.find((row) => row[KEY] === autoSelect);\n if (row) {\n selectRow(row);\n } else {\n console.warn(\n `[useDataSource] autoSelect row key ${autoSelect} not in viewport`,\n );\n }\n } else if (message.rows.length > 0) {\n selectRow(message.rows[0]);\n }\n }\n } else if (message.size === 0) {\n setData([]);\n } else if (typeof message.size === \"number\") {\n data.current = dataWindow.data;\n hasUpdated.current = true;\n }\n } else if (message.type === \"viewport-clear\") {\n onSizeChange?.(0);\n dataWindow.setRowCount(0);\n setData([]);\n\n if (isMounted.current === false) {\n console.log(\"setting state whilst unmounted\");\n }\n\n forceUpdate({});\n } else {\n console.log(`useDataSource unexpected message ${message.type}`);\n }\n },\n [autoSelect, dataWindow, onSizeChange, onSubscribed, selectRow, setData],\n );\n\n const getSelectedRows = useCallback(() => {\n return dataWindow.getSelectedRows();\n }, [dataWindow]);\n\n useEffect(() => {\n if (dataSource.status === \"disabled\") {\n dataSource.enable?.(datasourceMessageHandler);\n }\n }, [dataSource, datasourceMessageHandler]);\n\n const setRange = useCallback(\n (viewportRange: VuuRange) => {\n if (!rangeRef.current.equals(viewportRange)) {\n const range = Range(\n viewportRange.from,\n viewportRange.to,\n renderBufferSize,\n );\n\n dataWindow.setRange(range.withBuffer);\n\n if (\n dataSource.status !== \"subscribed\" &&\n dataSource.status !== \"subscribing\" &&\n dataSource.status !== \"enabling\"\n ) {\n dataSource?.subscribe(\n {\n range,\n revealSelected,\n selectedKeyValues: autoSelectRowKey\n ? [autoSelectRowKey]\n : undefined,\n },\n datasourceMessageHandler,\n );\n } else {\n dataSource.range = rangeRef.current = range;\n }\n }\n },\n [\n autoSelectRowKey,\n dataSource,\n dataWindow,\n datasourceMessageHandler,\n renderBufferSize,\n revealSelected,\n ],\n );\n\n useEffect(() => {\n isMounted.current = true;\n if (dataSource.status !== \"initialising\") {\n dataSource.resume?.(datasourceMessageHandler);\n\n if (dataSource.range.from > 0) {\n // UI does not currently restore scroll position, so always reset to top of dataset\n const { from, to } = rangeRef.current.reset;\n setRange({ from, to });\n }\n }\n return () => {\n isMounted.current = false;\n dataSource.suspend?.(\n suspenseProps?.escalateToDisable,\n suspenseProps?.escalateDelay,\n );\n };\n }, [dataSource, datasourceMessageHandler, setRange, suspenseProps]);\n\n const removeColumnDataFromCache = useCallback(\n (indexOfRemovedColumn: number) => {\n dataWindow.spliceDataAtIndex(indexOfRemovedColumn);\n data.current = dataWindow.data;\n },\n [dataWindow],\n );\n\n return {\n data: data.current,\n dataRef: data,\n getSelectedRows,\n range: rangeRef.current,\n removeColumnDataFromCache,\n setRange,\n };\n};\n"],"names":["row"],"mappings":"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"}
@@ -42,6 +42,7 @@ const useCellFocus = ({
42
42
  }
43
43
  }
44
44
  state.cellPos = cellPos;
45
+ console.log(`[useCellFocus] requestScroll ${cellPos[0]}`);
45
46
  requestScroll?.({ type: "scroll-row", rowIndex: cellPos[0] });
46
47
  activeCell.focus({ preventScroll: true });
47
48
  }
@@ -1 +1 @@
1
- {"version":3,"file":"useCellFocus.js","sources":["../../../packages/vuu-table/src/useCellFocus.ts"],"sourcesContent":["import {\n KeyboardEventHandler,\n RefCallback,\n RefObject,\n useCallback,\n} from \"react\";\nimport {\n dataCellQuery,\n getTableCell,\n headerCellQuery,\n} from \"./table-dom-utils\";\nimport { ScrollRequestHandler } from \"./useTableScroll\";\nimport { isArrowKey, queryClosest } from \"@vuu-ui/vuu-utils\";\nimport { CellPos } from \"@vuu-ui/vuu-table-types\";\nimport type { ICellFocusState } from \"./CellFocusState\";\n\nexport interface CellFocusHookProps {\n cellFocusStateRef: RefObject<ICellFocusState>;\n containerRef: RefObject<HTMLElement | null>;\n disableFocus?: boolean;\n requestScroll?: ScrollRequestHandler;\n}\n\nconst getCellPosition = (el: HTMLElement) => {\n const top = parseInt(el.parentElement?.style.top ?? \"-1\");\n return { top };\n};\n\nconst isDifferentCellPosition = (\n currentPos: CellPos | undefined,\n newPos: CellPos,\n) => {\n if (currentPos === undefined) {\n return true;\n }\n return currentPos[0] !== newPos[0] || currentPos[1] !== newPos[1];\n};\n\nexport type FocusCell = (cellPos: CellPos, fromKeyboard?: boolean) => void;\n\nexport const useCellFocus = ({\n cellFocusStateRef,\n containerRef,\n disableFocus = false,\n requestScroll,\n}: CellFocusHookProps) => {\n const focusCellPlaceholderRef = useCallback<RefCallback<HTMLDivElement>>(\n (el) => {\n cellFocusStateRef.current.placeholderEl = el;\n },\n [cellFocusStateRef],\n );\n\n const focusCell = useCallback<FocusCell>(\n (cellPos) => {\n if (containerRef.current) {\n const { current: state } = cellFocusStateRef;\n if (isDifferentCellPosition(state.cellPos, cellPos)) {\n const activeCell = getTableCell(containerRef, cellPos);\n if (activeCell) {\n if (activeCell !== state.el) {\n state.el?.removeAttribute(\"tabindex\");\n activeCell.setAttribute(\"tabindex\", \"0\");\n\n // TODO no need to measure if we're navigating horizontally\n // state.cellPos = cellPos;\n state.el = activeCell;\n state.pos = getCellPosition(activeCell);\n state.outsideViewport = false;\n\n if (state.placeholderEl) {\n state.placeholderEl.style.top = `${state.pos.top}px`;\n }\n }\n state.cellPos = cellPos;\n\n // TODO needs to be scroll cell to accommodate horizontal virtualization\n requestScroll?.({ type: \"scroll-row\", rowIndex: cellPos[0] });\n activeCell.focus({ preventScroll: true });\n }\n }\n }\n },\n [cellFocusStateRef, containerRef, requestScroll],\n );\n\n const setTableBodyRef = useCallback<RefCallback<HTMLDivElement>>(\n (el) => {\n if (el) {\n const { current: state } = cellFocusStateRef;\n const table = queryClosest<HTMLDivElement>(el, \".vuuTable\");\n if (table) {\n if (state.el === null && !disableFocus) {\n const headerCell = table.querySelector<HTMLDivElement>(\n headerCellQuery(1),\n );\n if (headerCell) {\n headerCell.setAttribute(\"tabindex\", \"0\");\n state.cellPos = [1, 1];\n state.el = headerCell;\n state.pos = { top: -20 };\n if (state.placeholderEl) {\n state.placeholderEl.style.top = `-20px`;\n }\n } else {\n const cell = table.querySelector<HTMLDivElement>(\n dataCellQuery(0, 0),\n );\n if (cell) {\n cell.setAttribute(\"tabindex\", \"0\");\n state.cellPos = [1, 1];\n state.el = cell;\n state.pos = { top: 0 };\n if (state.placeholderEl) {\n state.placeholderEl.style.top = `0px`;\n }\n }\n }\n }\n }\n }\n },\n [cellFocusStateRef, disableFocus],\n );\n\n const focusCellPlaceholderKeyDown = useCallback<KeyboardEventHandler>(\n (evt) => {\n const { outsideViewport, pos } = cellFocusStateRef.current;\n if (pos && isArrowKey(evt.key)) {\n // TODO depends on whether we're scrolling up or down\n if (outsideViewport === \"above\") {\n requestScroll?.({ type: \"scroll-top\", scrollPos: pos.top });\n } else if (outsideViewport === \"below\") {\n requestScroll?.({ type: \"scroll-bottom\", scrollPos: pos.top });\n } else {\n throw Error(\n `cellFocusPlaceholder should not have focus if inside viewport`,\n );\n }\n }\n },\n [cellFocusStateRef, requestScroll],\n );\n\n return {\n focusCell,\n focusCellPlaceholderKeyDown,\n focusCellPlaceholderRef,\n setTableBodyRef,\n };\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useCellFocus.js","sources":["../../../packages/vuu-table/src/useCellFocus.ts"],"sourcesContent":["import {\n KeyboardEventHandler,\n RefCallback,\n RefObject,\n useCallback,\n} from \"react\";\nimport {\n dataCellQuery,\n getTableCell,\n headerCellQuery,\n} from \"./table-dom-utils\";\nimport { ScrollRequestHandler } from \"./useTableScroll\";\nimport { isArrowKey, queryClosest } from \"@vuu-ui/vuu-utils\";\nimport { CellPos } from \"@vuu-ui/vuu-table-types\";\nimport type { ICellFocusState } from \"./CellFocusState\";\n\nexport interface CellFocusHookProps {\n cellFocusStateRef: RefObject<ICellFocusState>;\n containerRef: RefObject<HTMLElement | null>;\n disableFocus?: boolean;\n requestScroll?: ScrollRequestHandler;\n}\n\nconst getCellPosition = (el: HTMLElement) => {\n const top = parseInt(el.parentElement?.style.top ?? \"-1\");\n return { top };\n};\n\nconst isDifferentCellPosition = (\n currentPos: CellPos | undefined,\n newPos: CellPos,\n) => {\n if (currentPos === undefined) {\n return true;\n }\n return currentPos[0] !== newPos[0] || currentPos[1] !== newPos[1];\n};\n\nexport type FocusCell = (cellPos: CellPos, fromKeyboard?: boolean) => void;\n\nexport const useCellFocus = ({\n cellFocusStateRef,\n containerRef,\n disableFocus = false,\n requestScroll,\n}: CellFocusHookProps) => {\n const focusCellPlaceholderRef = useCallback<RefCallback<HTMLDivElement>>(\n (el) => {\n cellFocusStateRef.current.placeholderEl = el;\n },\n [cellFocusStateRef],\n );\n\n const focusCell = useCallback<FocusCell>(\n (cellPos) => {\n if (containerRef.current) {\n const { current: state } = cellFocusStateRef;\n if (isDifferentCellPosition(state.cellPos, cellPos)) {\n const activeCell = getTableCell(containerRef, cellPos);\n if (activeCell) {\n if (activeCell !== state.el) {\n state.el?.removeAttribute(\"tabindex\");\n activeCell.setAttribute(\"tabindex\", \"0\");\n\n // TODO no need to measure if we're navigating horizontally\n // state.cellPos = cellPos;\n state.el = activeCell;\n state.pos = getCellPosition(activeCell);\n state.outsideViewport = false;\n\n if (state.placeholderEl) {\n state.placeholderEl.style.top = `${state.pos.top}px`;\n }\n }\n state.cellPos = cellPos;\n\n // TODO needs to be scroll cell to accommodate horizontal virtualization\n console.log(`[useCellFocus] requestScroll ${cellPos[0]}`);\n\n requestScroll?.({ type: \"scroll-row\", rowIndex: cellPos[0] });\n activeCell.focus({ preventScroll: true });\n }\n }\n }\n },\n [cellFocusStateRef, containerRef, requestScroll],\n );\n\n const setTableBodyRef = useCallback<RefCallback<HTMLDivElement>>(\n (el) => {\n if (el) {\n const { current: state } = cellFocusStateRef;\n const table = queryClosest<HTMLDivElement>(el, \".vuuTable\");\n if (table) {\n if (state.el === null && !disableFocus) {\n const headerCell = table.querySelector<HTMLDivElement>(\n headerCellQuery(1),\n );\n if (headerCell) {\n headerCell.setAttribute(\"tabindex\", \"0\");\n state.cellPos = [1, 1];\n state.el = headerCell;\n state.pos = { top: -20 };\n if (state.placeholderEl) {\n state.placeholderEl.style.top = `-20px`;\n }\n } else {\n const cell = table.querySelector<HTMLDivElement>(\n dataCellQuery(0, 0),\n );\n if (cell) {\n cell.setAttribute(\"tabindex\", \"0\");\n state.cellPos = [1, 1];\n state.el = cell;\n state.pos = { top: 0 };\n if (state.placeholderEl) {\n state.placeholderEl.style.top = `0px`;\n }\n }\n }\n }\n }\n }\n },\n [cellFocusStateRef, disableFocus],\n );\n\n const focusCellPlaceholderKeyDown = useCallback<KeyboardEventHandler>(\n (evt) => {\n const { outsideViewport, pos } = cellFocusStateRef.current;\n if (pos && isArrowKey(evt.key)) {\n // TODO depends on whether we're scrolling up or down\n if (outsideViewport === \"above\") {\n requestScroll?.({ type: \"scroll-top\", scrollPos: pos.top });\n } else if (outsideViewport === \"below\") {\n requestScroll?.({ type: \"scroll-bottom\", scrollPos: pos.top });\n } else {\n throw Error(\n `cellFocusPlaceholder should not have focus if inside viewport`,\n );\n }\n }\n },\n [cellFocusStateRef, requestScroll],\n );\n\n return {\n focusCell,\n focusCellPlaceholderKeyDown,\n focusCellPlaceholderRef,\n setTableBodyRef,\n };\n};\n"],"names":[],"mappings":"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"}
@@ -8,15 +8,7 @@ const getMaxScroll = (container) => {
8
8
  const { clientHeight, clientWidth, scrollHeight, scrollWidth } = container;
9
9
  return [scrollWidth - clientWidth, scrollHeight - clientHeight];
10
10
  };
11
- const getScrollDirection = (prevScrollPositions, scrollPos) => {
12
- if (prevScrollPositions === void 0) {
13
- return void 0;
14
- } else {
15
- const { scrollTop: prevTop } = prevScrollPositions;
16
- return scrollPos > prevTop ? "fwd" : "bwd";
17
- }
18
- };
19
- const getPctScroll = (container, currentScrollPos) => {
11
+ const getPctScroll = (container) => {
20
12
  const {
21
13
  clientHeight,
22
14
  clientWidth,
@@ -28,13 +20,7 @@ const getPctScroll = (container, currentScrollPos) => {
28
20
  const maxScrollLeft = scrollWidth - clientWidth;
29
21
  const pctScrollLeft = scrollLeft / (scrollWidth - clientWidth);
30
22
  const maxScrollTop = scrollHeight - clientHeight;
31
- let pctScrollTop = scrollTop / (scrollHeight - clientHeight);
32
- const scrollDirection = getScrollDirection(currentScrollPos, scrollTop);
33
- if (scrollDirection === "fwd" && pctScrollTop > 0.99) {
34
- pctScrollTop = 1;
35
- } else if (scrollDirection === "bwd" && pctScrollTop < 0.02) {
36
- pctScrollTop = 0;
37
- }
23
+ const pctScrollTop = scrollTop / (scrollHeight - clientHeight);
38
24
  return [
39
25
  scrollLeft,
40
26
  pctScrollLeft,
@@ -158,7 +144,6 @@ const useTableScroll = ({
158
144
  focusState.outsideViewport = row < firstRow ? "above" : "below";
159
145
  } else if (isInViewport && !wasInViewport) {
160
146
  focusState.outsideViewport = false;
161
- focusCell?.(focusState.cellPos);
162
147
  }
163
148
  }
164
149
  }
@@ -166,7 +151,7 @@ const useTableScroll = ({
166
151
  },
167
152
  [
168
153
  cellFocusStateRef,
169
- focusCell,
154
+ // focusCell,
170
155
  getRowAtPosition,
171
156
  onVerticalScroll,
172
157
  onVerticalScrollInSitu,
@@ -180,7 +165,7 @@ const useTableScroll = ({
180
165
  const { current: contentContainer } = contentContainerRef;
181
166
  const { current: scrollbarContainer } = scrollbarContainerRef;
182
167
  if (scrollbarContainer && contentContainer) {
183
- const [scrollLeft, pctScrollLeft, , scrollTop, pctScrollTop] = getPctScroll(scrollbarContainer, scrollPos);
168
+ const [scrollLeft, pctScrollLeft, , scrollTop, pctScrollTop] = getPctScroll(scrollbarContainer);
184
169
  if (scrollLeft !== scrollPos.scrollLeft || scrollTop !== scrollPos.scrollTop) {
185
170
  scrollbarContainerScrolledRef.current = true;
186
171
  scrollPos.scrollLeft = scrollLeft;
@@ -206,7 +191,7 @@ const useTableScroll = ({
206
191
  contentContainerScrolledRef.current = false;
207
192
  } else if (contentContainer && scrollbarContainer) {
208
193
  scrollbarContainerScrolledRef.current = true;
209
- const [scrollLeft, pctScrollLeft, , scrollTop, pctScrollTop] = getPctScroll(scrollbarContainer, scrollPos);
194
+ const [scrollLeft, pctScrollLeft, , scrollTop, pctScrollTop] = getPctScroll(scrollbarContainer);
210
195
  scrollPos.scrollLeft = scrollLeft;
211
196
  scrollPos.scrollTop = scrollTop;
212
197
  const [maxScrollLeft, maxScrollTop] = getMaxScroll(scrollbarContainer);
@@ -1 +1 @@
1
- {"version":3,"file":"useTableScroll.js","sources":["../../../packages/vuu-table/src/useTableScroll.ts"],"sourcesContent":["import {\n getColumnsInViewport,\n itemsChanged,\n RowAtPositionFunc,\n} from \"@vuu-ui/vuu-utils\";\nimport type { VuuRange } from \"@vuu-ui/vuu-protocol-types\";\nimport {\n ForwardedRef,\n RefObject,\n useCallback,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport type { ViewportMeasurements } from \"./useTableViewport\";\nimport {\n getRowElementByAriaIndex,\n howFarIsRowOutsideViewport,\n} from \"./table-dom-utils\";\nimport type { RuntimeColumnDescriptor } from \"@vuu-ui/vuu-table-types\";\nimport { FocusCell } from \"./useCellFocus\";\nimport { ICellFocusState } from \"./CellFocusState\";\n\nexport type ScrollDirectionVertical = \"up\" | \"down\";\nexport type ScrollDirectionHorizontal = \"left\" | \"right\";\nexport type ScrollDirection =\n | ScrollDirectionVertical\n | ScrollDirectionHorizontal;\n\n/**\n * scroll into view the row at given pixel offset.\n */\nexport interface ScrollRequestPosition {\n instant?: boolean;\n scrollPos: number;\n type: \"scroll-top\" | \"scroll-bottom\";\n}\n\n/**\n * scroll into view the row at given row index posiiton.\n */\nexport interface ScrollRequestRow {\n rowIndex: number;\n type: \"scroll-row\";\n}\nexport interface ScrollRequestEnd {\n type: \"scroll-end\";\n direction: \"home\" | \"end\";\n}\n\nexport interface ScrollRequestPage {\n type: \"scroll-page\";\n direction: ScrollDirectionVertical;\n}\n\nexport type ScrollRequest =\n | ScrollRequestPage\n | ScrollRequestEnd\n | ScrollRequestRow\n | ScrollRequestPosition;\n\nexport type ScrollRequestHandler = (request: ScrollRequest) => void;\n\nexport interface ScrollingAPI {\n scrollToIndex: (itemIndex: number) => void;\n scrollToKey: (rowKey: string) => void;\n}\n\n/** How far we allow horizontal scroll movement before we recheck the rendered columns */\nconst SCROLL_MOVE_CHECK_THRESHOLD = 100;\n\n/** The buffer size in pixels that we allow for rendering columns just outside the viewport */\nconst HORIZONTAL_SCROLL_BUFFER = 200;\n\n/**\n * Return the maximum scroll positions for gioven container\n * @param container\n * @returns [maxScrollLeft, maxScrollTop]\n */\nconst getMaxScroll = (container: HTMLElement) => {\n const { clientHeight, clientWidth, scrollHeight, scrollWidth } = container;\n return [scrollWidth - clientWidth, scrollHeight - clientHeight];\n};\n\nconst getScrollDirection = (\n prevScrollPositions: ScrollPos | undefined,\n scrollPos: number,\n) => {\n if (prevScrollPositions === undefined) {\n return undefined;\n } else {\n const { scrollTop: prevTop } = prevScrollPositions;\n return scrollPos > prevTop ? \"fwd\" : \"bwd\";\n }\n};\n\nconst getPctScroll = (container: HTMLElement, currentScrollPos?: ScrollPos) => {\n const {\n clientHeight,\n clientWidth,\n scrollHeight,\n scrollLeft,\n scrollTop,\n scrollWidth,\n } = container;\n\n const maxScrollLeft = scrollWidth - clientWidth;\n const pctScrollLeft = scrollLeft / (scrollWidth - clientWidth);\n const maxScrollTop = scrollHeight - clientHeight;\n let pctScrollTop = scrollTop / (scrollHeight - clientHeight);\n\n const scrollDirection = getScrollDirection(currentScrollPos, scrollTop);\n\n if (scrollDirection === \"fwd\" && pctScrollTop > 0.99) {\n pctScrollTop = 1;\n } else if (scrollDirection === \"bwd\" && pctScrollTop < 0.02) {\n pctScrollTop = 0;\n }\n\n return [\n scrollLeft,\n pctScrollLeft,\n maxScrollLeft,\n scrollTop,\n pctScrollTop,\n maxScrollTop,\n ];\n};\n\nexport const noScrolling: ScrollingAPI = {\n scrollToIndex: () => undefined,\n scrollToKey: () => undefined,\n};\n\ninterface CallbackRefHookProps<T = HTMLElement> {\n onAttach?: (el: T) => void;\n onDetach: (el: T) => void;\n label?: string;\n}\n\nconst useCallbackRef = <T = HTMLElement>({\n onAttach,\n onDetach,\n}: CallbackRefHookProps<T>) => {\n const ref = useRef<T | null>(null);\n const callbackRef = useCallback(\n (el: T | null) => {\n if (el) {\n ref.current = el;\n onAttach?.(el);\n } else if (ref.current) {\n const { current: originalRef } = ref;\n ref.current = el;\n onDetach?.(originalRef);\n }\n },\n [onAttach, onDetach],\n );\n return callbackRef;\n};\n\ntype ScrollPos = {\n scrollLeft: number;\n scrollTop: number;\n};\n\nexport interface TableScrollHookProps {\n cellFocusStateRef: RefObject<ICellFocusState>;\n columns: RuntimeColumnDescriptor[];\n focusCell?: FocusCell;\n getRowAtPosition: RowAtPositionFunc;\n onHorizontalScroll?: (scrollLeft: number) => void;\n onVerticalScroll?: (scrollTop: number, pctScrollTop: number) => void;\n /**\n * When we have a virtualized scroll container, keyboard navigation is\n * performed `in situ`. We shift the range of rows rendered within the\n * viewport, whithout actually moving the scroll position\n */\n onVerticalScrollInSitu?: (rowIndexOffsetCount: number) => void;\n rowHeight: number;\n scrollingApiRef?: ForwardedRef<ScrollingAPI>;\n setRange: (range: VuuRange) => void;\n showPaginationControls?: boolean;\n viewportMeasurements: ViewportMeasurements;\n}\n\nexport const useTableScroll = ({\n cellFocusStateRef,\n columns,\n focusCell,\n getRowAtPosition,\n onHorizontalScroll,\n onVerticalScroll,\n onVerticalScrollInSitu,\n rowHeight,\n scrollingApiRef,\n setRange,\n viewportMeasurements,\n}: TableScrollHookProps) => {\n const firstRowRef = useRef<number>(0);\n const rowHeightRef = useRef(rowHeight);\n const contentContainerScrolledRef = useRef(false);\n const contentContainerPosRef = useRef<ScrollPos>({\n scrollTop: 0,\n scrollLeft: 0,\n });\n const scrollbarContainerScrolledRef = useRef(false);\n const scrollbarContainerPosRef = useRef<ScrollPos>({\n scrollTop: 0,\n scrollLeft: 0,\n });\n const scrollbarContainerRef = useRef<HTMLDivElement | null>(null);\n const contentContainerRef = useRef<HTMLDivElement | null>(null);\n const lastHorizontalScrollCheckPoint = useRef(0);\n\n const {\n appliedPageSize,\n isVirtualScroll,\n rowCount: viewportRowCount,\n totalHeaderHeight,\n usesMeasuredHeaderHeight,\n viewportBodyHeight,\n viewportWidth,\n } = viewportMeasurements;\n\n const columnsWithinViewportRef = useRef<RuntimeColumnDescriptor[]>([]);\n const [, forceRefresh] = useState({});\n\n const preSpanRef = useRef(0);\n\n useMemo(() => {\n const [visibleColumns, offset] = getColumnsInViewport(\n columns,\n contentContainerPosRef.current.scrollLeft,\n contentContainerPosRef.current.scrollLeft +\n viewportWidth +\n HORIZONTAL_SCROLL_BUFFER,\n );\n preSpanRef.current = offset;\n columnsWithinViewportRef.current = visibleColumns;\n }, [viewportWidth, columns]);\n\n const handleHorizontalScroll = useCallback(\n (scrollLeft: number) => {\n contentContainerPosRef.current.scrollLeft = scrollLeft;\n onHorizontalScroll?.(scrollLeft);\n\n if (\n Math.abs(scrollLeft - lastHorizontalScrollCheckPoint.current) >\n SCROLL_MOVE_CHECK_THRESHOLD\n ) {\n lastHorizontalScrollCheckPoint.current = scrollLeft;\n\n const [visibleColumns, pre] = getColumnsInViewport(\n columns,\n scrollLeft,\n scrollLeft + viewportWidth + HORIZONTAL_SCROLL_BUFFER,\n );\n\n if (itemsChanged(columnsWithinViewportRef.current, visibleColumns)) {\n preSpanRef.current = pre;\n columnsWithinViewportRef.current = visibleColumns;\n forceRefresh({});\n }\n }\n },\n [columns, onHorizontalScroll, viewportWidth],\n );\n const handleVerticalScroll = useCallback(\n (scrollTop: number, pctScrollTop: number) => {\n contentContainerPosRef.current.scrollTop = scrollTop;\n const { current: prevFirstRow } = firstRowRef;\n\n onVerticalScroll?.(scrollTop, pctScrollTop);\n const firstRow = getRowAtPosition(scrollTop);\n if (firstRow !== prevFirstRow) {\n firstRowRef.current = firstRow;\n const lastRow = firstRow + viewportRowCount;\n setRange({ from: firstRow, to: lastRow });\n\n // If we've scrolled the focused cell out of view, we need to remove\n // focus from it. The row element will be recycled and used as the\n // render target for a different DataRow, we do not want the focus\n // state of the cell to be preserved.\n // Conversely, if we scroll the focussed cell back into the viewport,\n // we must re-apply focus to it. We use the placeholder cell for this.\n const { current: focusState } = cellFocusStateRef;\n if (focusState.cellPos) {\n const prevLastRow = prevFirstRow + viewportRowCount;\n const [row] = focusState.cellPos;\n const wasInViewport = row >= prevFirstRow && row < prevLastRow;\n const isInViewport = row >= firstRow && row < lastRow;\n\n if (wasInViewport && !isInViewport) {\n focusState.placeholderEl?.focus({ preventScroll: true });\n focusState.outsideViewport = row < firstRow ? \"above\" : \"below\";\n } else if (isInViewport && !wasInViewport) {\n focusState.outsideViewport = false;\n focusCell?.(focusState.cellPos);\n }\n }\n }\n onVerticalScrollInSitu?.(0);\n },\n [\n cellFocusStateRef,\n focusCell,\n getRowAtPosition,\n onVerticalScroll,\n onVerticalScrollInSitu,\n setRange,\n viewportRowCount,\n ],\n );\n\n // Because of the amount of work done when we rerender a virtualised section\n // we may drop scroll events. Make sure we get the final resting position right\n // by remeasuring after a short delay.\n const scrollTimerRef = useRef<ReturnType<typeof setTimeout>>(null);\n const checkScrollbarScrollPosition = useCallback(() => {\n const { current: scrollPos } = scrollbarContainerPosRef;\n const { current: contentContainer } = contentContainerRef;\n\n const { current: scrollbarContainer } = scrollbarContainerRef;\n\n if (scrollbarContainer && contentContainer) {\n const [scrollLeft, pctScrollLeft, , scrollTop, pctScrollTop] =\n getPctScroll(scrollbarContainer, scrollPos);\n\n if (\n scrollLeft !== scrollPos.scrollLeft ||\n scrollTop !== scrollPos.scrollTop\n ) {\n scrollbarContainerScrolledRef.current = true;\n\n scrollPos.scrollLeft = scrollLeft;\n scrollPos.scrollTop = scrollTop;\n\n const [maxScrollLeft, maxScrollTop] = getMaxScroll(scrollbarContainer);\n const contentScrollLeft = Math.round(pctScrollLeft * maxScrollLeft);\n const contentScrollTop = pctScrollTop * maxScrollTop;\n\n contentContainer.scrollTo({\n left: contentScrollLeft,\n top: contentScrollTop,\n behavior: \"auto\",\n });\n }\n\n scrollTimerRef.current = null;\n }\n }, []);\n\n const handleScrollbarContainerScroll = useCallback(() => {\n const { current: contentContainer } = contentContainerRef;\n const { current: scrollbarContainer } = scrollbarContainerRef;\n const { current: contentContainerScrolled } = contentContainerScrolledRef;\n const { current: scrollPos } = scrollbarContainerPosRef;\n\n if (contentContainerScrolled) {\n contentContainerScrolledRef.current = false;\n } else if (contentContainer && scrollbarContainer) {\n scrollbarContainerScrolledRef.current = true;\n const [scrollLeft, pctScrollLeft, , scrollTop, pctScrollTop] =\n getPctScroll(scrollbarContainer, scrollPos);\n\n scrollPos.scrollLeft = scrollLeft;\n scrollPos.scrollTop = scrollTop;\n\n const [maxScrollLeft, maxScrollTop] = getMaxScroll(scrollbarContainer);\n const contentScrollLeft = Math.round(pctScrollLeft * maxScrollLeft);\n const contentScrollTop = pctScrollTop * maxScrollTop;\n\n contentContainer.scrollTo({\n left: contentScrollLeft,\n top: contentScrollTop,\n behavior: \"auto\",\n });\n }\n\n if (scrollTimerRef.current) {\n clearTimeout(scrollTimerRef.current);\n }\n scrollTimerRef.current = setTimeout(checkScrollbarScrollPosition, 60);\n\n onVerticalScrollInSitu?.(0);\n }, [checkScrollbarScrollPosition, onVerticalScrollInSitu]);\n\n const handleContentContainerScroll = useCallback(() => {\n const { current: scrollbarContainerScrolled } =\n scrollbarContainerScrolledRef;\n const { current: contentContainer } = contentContainerRef;\n const { current: scrollbarContainer } = scrollbarContainerRef;\n const { current: scrollPos } = contentContainerPosRef;\n\n if (contentContainer && scrollbarContainer) {\n const [\n scrollLeft,\n pctScrollLeft,\n maxScrollLeft,\n scrollTop,\n pctScrollTop,\n maxScrollTop,\n ] = getPctScroll(contentContainer);\n\n contentContainerScrolledRef.current = true;\n\n if (scrollbarContainerScrolled) {\n scrollbarContainerScrolledRef.current = false;\n } else {\n scrollbarContainer.scrollLeft = Math.round(\n pctScrollLeft * maxScrollLeft,\n );\n scrollbarContainer.scrollTop = pctScrollTop * maxScrollTop;\n }\n\n if (scrollPos.scrollTop !== scrollTop) {\n handleVerticalScroll(scrollTop, pctScrollTop);\n }\n if (scrollPos.scrollLeft !== scrollLeft) {\n handleHorizontalScroll(scrollLeft);\n }\n }\n }, [handleVerticalScroll, handleHorizontalScroll]);\n\n const handleAttachScrollbarContainer = useCallback(\n (el: HTMLDivElement) => {\n scrollbarContainerRef.current = el;\n el.addEventListener(\"scroll\", handleScrollbarContainerScroll, {\n passive: true,\n });\n },\n [handleScrollbarContainerScroll],\n );\n\n const handleDetachScrollbarContainer = useCallback(\n (el: HTMLDivElement) => {\n scrollbarContainerRef.current = null;\n el.removeEventListener(\"scroll\", handleScrollbarContainerScroll);\n },\n [handleScrollbarContainerScroll],\n );\n\n const handleAttachContentContainer = useCallback(\n (el: HTMLDivElement) => {\n contentContainerRef.current = el;\n el.addEventListener(\"scroll\", handleContentContainerScroll, {\n passive: true,\n });\n },\n [handleContentContainerScroll],\n );\n\n const handleDetachContentContainer = useCallback(\n (el: HTMLDivElement) => {\n contentContainerRef.current = null;\n el.removeEventListener(\"scroll\", handleContentContainerScroll);\n },\n [handleContentContainerScroll],\n );\n\n const contentContainerCallbackRef = useCallbackRef({\n onAttach: handleAttachContentContainer,\n onDetach: handleDetachContentContainer,\n });\n\n const scrollbarContainerCallbackRef = useCallbackRef({\n onAttach: handleAttachScrollbarContainer,\n onDetach: handleDetachScrollbarContainer,\n });\n\n const requestScroll: ScrollRequestHandler = useCallback(\n (scrollRequest) => {\n const { current: contentContainer } = contentContainerRef;\n const { current: scrollbarContainer } = scrollbarContainerRef;\n\n if (contentContainer) {\n const [maxScrollLeft, maxScrollTop] = getMaxScroll(contentContainer);\n const { scrollLeft, scrollTop } = contentContainer;\n contentContainerScrolledRef.current = false;\n switch (scrollRequest.type) {\n case \"scroll-top\":\n {\n // special case for setting scroll position immediately back to top\n if (\n scrollRequest.instant &&\n scrollRequest.scrollPos === 0 &&\n scrollbarContainer\n ) {\n contentContainer.scrollTop = 0;\n scrollbarContainer.scrollTop = 0;\n } else {\n contentContainer.scrollTo({\n top: scrollRequest.scrollPos,\n left: scrollLeft,\n behavior: \"instant\",\n });\n }\n }\n break;\n case \"scroll-bottom\":\n {\n contentContainer.scrollTo({\n top:\n scrollRequest.scrollPos -\n (viewportBodyHeight - 2 * rowHeight),\n left: scrollLeft,\n behavior: \"instant\",\n });\n }\n break;\n case \"scroll-row\":\n {\n const activeRow = getRowElementByAriaIndex(\n contentContainer,\n scrollRequest.rowIndex,\n );\n\n if (activeRow !== null) {\n const [direction, distance] = howFarIsRowOutsideViewport(\n activeRow,\n totalHeaderHeight,\n );\n if (direction && distance) {\n if (isVirtualScroll) {\n const offset = direction === \"down\" ? 1 : -1;\n onVerticalScrollInSitu?.(offset);\n const firstRow = firstRowRef.current + offset;\n firstRowRef.current = firstRow;\n setRange({\n from: firstRow,\n to: firstRow + viewportRowCount,\n });\n } else {\n let newScrollLeft = scrollLeft;\n let newScrollTop = scrollTop;\n if (direction === \"up\" || direction === \"down\") {\n newScrollTop = Math.min(\n Math.max(0, scrollTop + distance),\n maxScrollTop,\n );\n } else {\n newScrollLeft = Math.min(\n Math.max(0, scrollLeft + distance),\n maxScrollLeft,\n );\n }\n contentContainer.scrollTo({\n top: newScrollTop,\n left: newScrollLeft,\n // avoid behaviour: 'smooth', doesn't work correctly\n behavior: \"instant\",\n });\n }\n }\n }\n }\n break;\n case \"scroll-page\":\n {\n const { direction } = scrollRequest;\n if (isVirtualScroll) {\n const offset =\n direction === \"down\" ? viewportRowCount : -viewportRowCount;\n onVerticalScrollInSitu?.(offset);\n const firstRow = firstRowRef.current + offset;\n firstRowRef.current = firstRow;\n setRange({ from: firstRow, to: firstRow + viewportRowCount });\n } else {\n const scrollBy =\n direction === \"down\" ? appliedPageSize : -appliedPageSize;\n const newScrollTop = Math.min(\n Math.max(0, scrollTop + scrollBy),\n maxScrollTop,\n );\n contentContainer.scrollTo({\n top: newScrollTop,\n left: scrollLeft,\n behavior: \"auto\",\n });\n }\n }\n break;\n case \"scroll-end\":\n {\n const { direction } = scrollRequest;\n const scrollTo = direction === \"end\" ? maxScrollTop : 0;\n contentContainer.scrollTo({\n top: scrollTo,\n left: contentContainer.scrollLeft,\n behavior: \"auto\",\n });\n }\n break;\n default:\n console.warn(`unexpected scroll request ${scrollRequest[\"type\"]}`);\n }\n }\n },\n [\n appliedPageSize,\n isVirtualScroll,\n onVerticalScrollInSitu,\n rowHeight,\n setRange,\n totalHeaderHeight,\n viewportBodyHeight,\n viewportRowCount,\n ],\n );\n\n const scrollHandles: ScrollingAPI = useMemo(\n // TODO not complete yet\n () => ({\n scrollToIndex: (rowIndex: number) => {\n if (scrollbarContainerRef.current) {\n // TODO hardcoded rowHeight\n const scrollPos = (rowIndex - 30) * 20;\n scrollbarContainerRef.current.scrollTop = scrollPos;\n }\n },\n scrollToKey: (rowKey: string) => {\n console.log(`scrollToKey ${rowKey}`);\n },\n }),\n [],\n );\n\n useImperativeHandle(scrollingApiRef, () => {\n if (scrollbarContainerRef.current) {\n return scrollHandles;\n } else {\n return noScrolling;\n }\n }, [scrollHandles]);\n\n useEffect(() => {\n if (rowHeight !== rowHeightRef.current) {\n rowHeightRef.current = rowHeight;\n if (contentContainerPosRef.current.scrollTop > 0) {\n if (contentContainerRef.current) {\n contentContainerRef.current.scrollTop = 0;\n }\n }\n } else if (usesMeasuredHeaderHeight) {\n const { current: from } = firstRowRef;\n const rowRange = { from, to: from + viewportRowCount };\n setRange(rowRange);\n }\n }, [rowHeight, setRange, usesMeasuredHeaderHeight, viewportRowCount]);\n\n return {\n columnsWithinViewport: columnsWithinViewportRef.current,\n /** Ref to be assigned to ScrollbarContainer */\n scrollbarContainerRef: scrollbarContainerCallbackRef,\n /** Ref to be assigned to ContentContainer */\n contentContainerRef: contentContainerCallbackRef,\n /** Scroll the table */\n requestScroll,\n scrollTop: contentContainerPosRef.current.scrollTop,\n /** number of leading columns not rendered because of virtualization */\n virtualColSpan: preSpanRef.current,\n };\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useTableScroll.js","sources":["../../../packages/vuu-table/src/useTableScroll.ts"],"sourcesContent":["import {\n getColumnsInViewport,\n itemsChanged,\n RowAtPositionFunc,\n} from \"@vuu-ui/vuu-utils\";\nimport type { VuuRange } from \"@vuu-ui/vuu-protocol-types\";\nimport {\n ForwardedRef,\n RefObject,\n useCallback,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport type { ViewportMeasurements } from \"./useTableViewport\";\nimport {\n getRowElementByAriaIndex,\n howFarIsRowOutsideViewport,\n} from \"./table-dom-utils\";\nimport type { RuntimeColumnDescriptor } from \"@vuu-ui/vuu-table-types\";\nimport { FocusCell } from \"./useCellFocus\";\nimport { ICellFocusState } from \"./CellFocusState\";\n\nexport type ScrollDirectionVertical = \"up\" | \"down\";\nexport type ScrollDirectionHorizontal = \"left\" | \"right\";\nexport type ScrollDirection =\n | ScrollDirectionVertical\n | ScrollDirectionHorizontal;\n\n/**\n * scroll into view the row at given pixel offset.\n */\nexport interface ScrollRequestPosition {\n instant?: boolean;\n scrollPos: number;\n type: \"scroll-top\" | \"scroll-bottom\";\n}\n\n/**\n * scroll into view the row at given row index posiiton.\n */\nexport interface ScrollRequestRow {\n rowIndex: number;\n type: \"scroll-row\";\n}\nexport interface ScrollRequestEnd {\n type: \"scroll-end\";\n direction: \"home\" | \"end\";\n}\n\nexport interface ScrollRequestPage {\n type: \"scroll-page\";\n direction: ScrollDirectionVertical;\n}\n\nexport type ScrollRequest =\n | ScrollRequestPage\n | ScrollRequestEnd\n | ScrollRequestRow\n | ScrollRequestPosition;\n\nexport type ScrollRequestHandler = (request: ScrollRequest) => void;\n\nexport interface ScrollingAPI {\n scrollToIndex: (itemIndex: number) => void;\n scrollToKey: (rowKey: string) => void;\n}\n\n/** How far we allow horizontal scroll movement before we recheck the rendered columns */\nconst SCROLL_MOVE_CHECK_THRESHOLD = 100;\n\n/** The buffer size in pixels that we allow for rendering columns just outside the viewport */\nconst HORIZONTAL_SCROLL_BUFFER = 200;\n\n/**\n * Return the maximum scroll positions for gioven container\n * @param container\n * @returns [maxScrollLeft, maxScrollTop]\n */\nconst getMaxScroll = (container: HTMLElement) => {\n const { clientHeight, clientWidth, scrollHeight, scrollWidth } = container;\n return [scrollWidth - clientWidth, scrollHeight - clientHeight];\n};\n\nconst getPctScroll = (container: HTMLElement) => {\n const {\n clientHeight,\n clientWidth,\n scrollHeight,\n scrollLeft,\n scrollTop,\n scrollWidth,\n } = container;\n\n const maxScrollLeft = scrollWidth - clientWidth;\n const pctScrollLeft = scrollLeft / (scrollWidth - clientWidth);\n const maxScrollTop = scrollHeight - clientHeight;\n const pctScrollTop = scrollTop / (scrollHeight - clientHeight);\n\n return [\n scrollLeft,\n pctScrollLeft,\n maxScrollLeft,\n scrollTop,\n pctScrollTop,\n maxScrollTop,\n ];\n};\n\nexport const noScrolling: ScrollingAPI = {\n scrollToIndex: () => undefined,\n scrollToKey: () => undefined,\n};\n\ninterface CallbackRefHookProps<T = HTMLElement> {\n onAttach?: (el: T) => void;\n onDetach: (el: T) => void;\n label?: string;\n}\n\nconst useCallbackRef = <T = HTMLElement>({\n onAttach,\n onDetach,\n}: CallbackRefHookProps<T>) => {\n const ref = useRef<T | null>(null);\n const callbackRef = useCallback(\n (el: T | null) => {\n if (el) {\n ref.current = el;\n onAttach?.(el);\n } else if (ref.current) {\n const { current: originalRef } = ref;\n ref.current = el;\n onDetach?.(originalRef);\n }\n },\n [onAttach, onDetach],\n );\n return callbackRef;\n};\n\ntype ScrollPos = {\n scrollLeft: number;\n scrollTop: number;\n};\n\nexport interface TableScrollHookProps {\n cellFocusStateRef: RefObject<ICellFocusState>;\n columns: RuntimeColumnDescriptor[];\n focusCell?: FocusCell;\n getRowAtPosition: RowAtPositionFunc;\n onHorizontalScroll?: (scrollLeft: number) => void;\n onVerticalScroll?: (scrollTop: number, pctScrollTop: number) => void;\n /**\n * When we have a virtualized scroll container, keyboard navigation is\n * performed `in situ`. We shift the range of rows rendered within the\n * viewport, whithout actually moving the scroll position\n */\n onVerticalScrollInSitu?: (rowIndexOffsetCount: number) => void;\n rowHeight: number;\n scrollingApiRef?: ForwardedRef<ScrollingAPI>;\n setRange: (range: VuuRange) => void;\n showPaginationControls?: boolean;\n viewportMeasurements: ViewportMeasurements;\n}\n\nexport const useTableScroll = ({\n cellFocusStateRef,\n columns,\n focusCell,\n getRowAtPosition,\n onHorizontalScroll,\n onVerticalScroll,\n onVerticalScrollInSitu,\n rowHeight,\n scrollingApiRef,\n setRange,\n viewportMeasurements,\n}: TableScrollHookProps) => {\n const firstRowRef = useRef<number>(0);\n const rowHeightRef = useRef(rowHeight);\n const contentContainerScrolledRef = useRef(false);\n const contentContainerPosRef = useRef<ScrollPos>({\n scrollTop: 0,\n scrollLeft: 0,\n });\n const scrollbarContainerScrolledRef = useRef(false);\n const scrollbarContainerPosRef = useRef<ScrollPos>({\n scrollTop: 0,\n scrollLeft: 0,\n });\n const scrollbarContainerRef = useRef<HTMLDivElement | null>(null);\n const contentContainerRef = useRef<HTMLDivElement | null>(null);\n const lastHorizontalScrollCheckPoint = useRef(0);\n\n const {\n appliedPageSize,\n isVirtualScroll,\n rowCount: viewportRowCount,\n totalHeaderHeight,\n usesMeasuredHeaderHeight,\n viewportBodyHeight,\n viewportWidth,\n } = viewportMeasurements;\n\n const columnsWithinViewportRef = useRef<RuntimeColumnDescriptor[]>([]);\n const [, forceRefresh] = useState({});\n\n const preSpanRef = useRef(0);\n\n useMemo(() => {\n const [visibleColumns, offset] = getColumnsInViewport(\n columns,\n contentContainerPosRef.current.scrollLeft,\n contentContainerPosRef.current.scrollLeft +\n viewportWidth +\n HORIZONTAL_SCROLL_BUFFER,\n );\n preSpanRef.current = offset;\n columnsWithinViewportRef.current = visibleColumns;\n }, [viewportWidth, columns]);\n\n const handleHorizontalScroll = useCallback(\n (scrollLeft: number) => {\n contentContainerPosRef.current.scrollLeft = scrollLeft;\n onHorizontalScroll?.(scrollLeft);\n\n if (\n Math.abs(scrollLeft - lastHorizontalScrollCheckPoint.current) >\n SCROLL_MOVE_CHECK_THRESHOLD\n ) {\n lastHorizontalScrollCheckPoint.current = scrollLeft;\n\n const [visibleColumns, pre] = getColumnsInViewport(\n columns,\n scrollLeft,\n scrollLeft + viewportWidth + HORIZONTAL_SCROLL_BUFFER,\n );\n\n if (itemsChanged(columnsWithinViewportRef.current, visibleColumns)) {\n preSpanRef.current = pre;\n columnsWithinViewportRef.current = visibleColumns;\n forceRefresh({});\n }\n }\n },\n [columns, onHorizontalScroll, viewportWidth],\n );\n const handleVerticalScroll = useCallback(\n (scrollTop: number, pctScrollTop: number) => {\n contentContainerPosRef.current.scrollTop = scrollTop;\n const { current: prevFirstRow } = firstRowRef;\n\n onVerticalScroll?.(scrollTop, pctScrollTop);\n const firstRow = getRowAtPosition(scrollTop);\n if (firstRow !== prevFirstRow) {\n firstRowRef.current = firstRow;\n const lastRow = firstRow + viewportRowCount;\n setRange({ from: firstRow, to: lastRow });\n\n // If we've scrolled the focused cell out of view, we need to remove\n // focus from it. The row element will be recycled and used as the\n // render target for a different DataRow, we do not want the focus\n // state of the cell to be preserved.\n // Conversely, if we scroll the focussed cell back into the viewport,\n // we must re-apply focus to it. We use the placeholder cell for this.\n const { current: focusState } = cellFocusStateRef;\n if (focusState.cellPos) {\n const prevLastRow = prevFirstRow + viewportRowCount;\n const [row] = focusState.cellPos;\n const wasInViewport = row >= prevFirstRow && row < prevLastRow;\n const isInViewport = row >= firstRow && row < lastRow;\n\n if (wasInViewport && !isInViewport) {\n focusState.placeholderEl?.focus({ preventScroll: true });\n focusState.outsideViewport = row < firstRow ? \"above\" : \"below\";\n } else if (isInViewport && !wasInViewport) {\n focusState.outsideViewport = false;\n // focusCell?.(focusState.cellPos);\n }\n }\n }\n onVerticalScrollInSitu?.(0);\n },\n [\n cellFocusStateRef,\n // focusCell,\n getRowAtPosition,\n onVerticalScroll,\n onVerticalScrollInSitu,\n setRange,\n viewportRowCount,\n ],\n );\n\n // Because of the amount of work done when we rerender a virtualised section\n // we may drop scroll events. Make sure we get the final resting position right\n // by remeasuring after a short delay.\n const scrollTimerRef = useRef<ReturnType<typeof setTimeout>>(null);\n const checkScrollbarScrollPosition = useCallback(() => {\n const { current: scrollPos } = scrollbarContainerPosRef;\n const { current: contentContainer } = contentContainerRef;\n\n const { current: scrollbarContainer } = scrollbarContainerRef;\n\n if (scrollbarContainer && contentContainer) {\n const [scrollLeft, pctScrollLeft, , scrollTop, pctScrollTop] =\n getPctScroll(scrollbarContainer);\n\n if (\n scrollLeft !== scrollPos.scrollLeft ||\n scrollTop !== scrollPos.scrollTop\n ) {\n scrollbarContainerScrolledRef.current = true;\n\n scrollPos.scrollLeft = scrollLeft;\n scrollPos.scrollTop = scrollTop;\n\n const [maxScrollLeft, maxScrollTop] = getMaxScroll(scrollbarContainer);\n const contentScrollLeft = Math.round(pctScrollLeft * maxScrollLeft);\n const contentScrollTop = pctScrollTop * maxScrollTop;\n\n contentContainer.scrollTo({\n left: contentScrollLeft,\n top: contentScrollTop,\n behavior: \"auto\",\n });\n }\n\n scrollTimerRef.current = null;\n }\n }, []);\n\n const handleScrollbarContainerScroll = useCallback(() => {\n const { current: contentContainer } = contentContainerRef;\n const { current: scrollbarContainer } = scrollbarContainerRef;\n const { current: contentContainerScrolled } = contentContainerScrolledRef;\n const { current: scrollPos } = scrollbarContainerPosRef;\n\n if (contentContainerScrolled) {\n contentContainerScrolledRef.current = false;\n } else if (contentContainer && scrollbarContainer) {\n scrollbarContainerScrolledRef.current = true;\n const [scrollLeft, pctScrollLeft, , scrollTop, pctScrollTop] =\n getPctScroll(scrollbarContainer);\n\n scrollPos.scrollLeft = scrollLeft;\n scrollPos.scrollTop = scrollTop;\n\n const [maxScrollLeft, maxScrollTop] = getMaxScroll(scrollbarContainer);\n const contentScrollLeft = Math.round(pctScrollLeft * maxScrollLeft);\n const contentScrollTop = pctScrollTop * maxScrollTop;\n\n contentContainer.scrollTo({\n left: contentScrollLeft,\n top: contentScrollTop,\n behavior: \"auto\",\n });\n }\n\n if (scrollTimerRef.current) {\n clearTimeout(scrollTimerRef.current);\n }\n scrollTimerRef.current = setTimeout(checkScrollbarScrollPosition, 60);\n\n onVerticalScrollInSitu?.(0);\n }, [checkScrollbarScrollPosition, onVerticalScrollInSitu]);\n\n const handleContentContainerScroll = useCallback(() => {\n const { current: scrollbarContainerScrolled } =\n scrollbarContainerScrolledRef;\n const { current: contentContainer } = contentContainerRef;\n const { current: scrollbarContainer } = scrollbarContainerRef;\n const { current: scrollPos } = contentContainerPosRef;\n\n if (contentContainer && scrollbarContainer) {\n const [\n scrollLeft,\n pctScrollLeft,\n maxScrollLeft,\n scrollTop,\n pctScrollTop,\n maxScrollTop,\n ] = getPctScroll(contentContainer);\n\n contentContainerScrolledRef.current = true;\n\n if (scrollbarContainerScrolled) {\n scrollbarContainerScrolledRef.current = false;\n } else {\n scrollbarContainer.scrollLeft = Math.round(\n pctScrollLeft * maxScrollLeft,\n );\n scrollbarContainer.scrollTop = pctScrollTop * maxScrollTop;\n }\n\n if (scrollPos.scrollTop !== scrollTop) {\n handleVerticalScroll(scrollTop, pctScrollTop);\n }\n if (scrollPos.scrollLeft !== scrollLeft) {\n handleHorizontalScroll(scrollLeft);\n }\n }\n }, [handleVerticalScroll, handleHorizontalScroll]);\n\n const handleAttachScrollbarContainer = useCallback(\n (el: HTMLDivElement) => {\n scrollbarContainerRef.current = el;\n el.addEventListener(\"scroll\", handleScrollbarContainerScroll, {\n passive: true,\n });\n },\n [handleScrollbarContainerScroll],\n );\n\n const handleDetachScrollbarContainer = useCallback(\n (el: HTMLDivElement) => {\n scrollbarContainerRef.current = null;\n el.removeEventListener(\"scroll\", handleScrollbarContainerScroll);\n },\n [handleScrollbarContainerScroll],\n );\n\n const handleAttachContentContainer = useCallback(\n (el: HTMLDivElement) => {\n contentContainerRef.current = el;\n el.addEventListener(\"scroll\", handleContentContainerScroll, {\n passive: true,\n });\n },\n [handleContentContainerScroll],\n );\n\n const handleDetachContentContainer = useCallback(\n (el: HTMLDivElement) => {\n contentContainerRef.current = null;\n el.removeEventListener(\"scroll\", handleContentContainerScroll);\n },\n [handleContentContainerScroll],\n );\n\n const contentContainerCallbackRef = useCallbackRef({\n onAttach: handleAttachContentContainer,\n onDetach: handleDetachContentContainer,\n });\n\n const scrollbarContainerCallbackRef = useCallbackRef({\n onAttach: handleAttachScrollbarContainer,\n onDetach: handleDetachScrollbarContainer,\n });\n\n const requestScroll: ScrollRequestHandler = useCallback(\n (scrollRequest) => {\n const { current: contentContainer } = contentContainerRef;\n const { current: scrollbarContainer } = scrollbarContainerRef;\n\n if (contentContainer) {\n const [maxScrollLeft, maxScrollTop] = getMaxScroll(contentContainer);\n const { scrollLeft, scrollTop } = contentContainer;\n contentContainerScrolledRef.current = false;\n switch (scrollRequest.type) {\n case \"scroll-top\":\n {\n // special case for setting scroll position immediately back to top\n if (\n scrollRequest.instant &&\n scrollRequest.scrollPos === 0 &&\n scrollbarContainer\n ) {\n contentContainer.scrollTop = 0;\n scrollbarContainer.scrollTop = 0;\n } else {\n contentContainer.scrollTo({\n top: scrollRequest.scrollPos,\n left: scrollLeft,\n behavior: \"instant\",\n });\n }\n }\n break;\n case \"scroll-bottom\":\n {\n contentContainer.scrollTo({\n top:\n scrollRequest.scrollPos -\n (viewportBodyHeight - 2 * rowHeight),\n left: scrollLeft,\n behavior: \"instant\",\n });\n }\n break;\n case \"scroll-row\":\n {\n const activeRow = getRowElementByAriaIndex(\n contentContainer,\n scrollRequest.rowIndex,\n );\n\n if (activeRow !== null) {\n const [direction, distance] = howFarIsRowOutsideViewport(\n activeRow,\n totalHeaderHeight,\n );\n if (direction && distance) {\n if (isVirtualScroll) {\n const offset = direction === \"down\" ? 1 : -1;\n onVerticalScrollInSitu?.(offset);\n const firstRow = firstRowRef.current + offset;\n firstRowRef.current = firstRow;\n setRange({\n from: firstRow,\n to: firstRow + viewportRowCount,\n });\n } else {\n let newScrollLeft = scrollLeft;\n let newScrollTop = scrollTop;\n if (direction === \"up\" || direction === \"down\") {\n newScrollTop = Math.min(\n Math.max(0, scrollTop + distance),\n maxScrollTop,\n );\n } else {\n newScrollLeft = Math.min(\n Math.max(0, scrollLeft + distance),\n maxScrollLeft,\n );\n }\n contentContainer.scrollTo({\n top: newScrollTop,\n left: newScrollLeft,\n // avoid behaviour: 'smooth', doesn't work correctly\n behavior: \"instant\",\n });\n }\n }\n }\n }\n break;\n case \"scroll-page\":\n {\n const { direction } = scrollRequest;\n if (isVirtualScroll) {\n const offset =\n direction === \"down\" ? viewportRowCount : -viewportRowCount;\n onVerticalScrollInSitu?.(offset);\n const firstRow = firstRowRef.current + offset;\n firstRowRef.current = firstRow;\n setRange({ from: firstRow, to: firstRow + viewportRowCount });\n } else {\n const scrollBy =\n direction === \"down\" ? appliedPageSize : -appliedPageSize;\n const newScrollTop = Math.min(\n Math.max(0, scrollTop + scrollBy),\n maxScrollTop,\n );\n contentContainer.scrollTo({\n top: newScrollTop,\n left: scrollLeft,\n behavior: \"auto\",\n });\n }\n }\n break;\n case \"scroll-end\":\n {\n const { direction } = scrollRequest;\n const scrollTo = direction === \"end\" ? maxScrollTop : 0;\n contentContainer.scrollTo({\n top: scrollTo,\n left: contentContainer.scrollLeft,\n behavior: \"auto\",\n });\n }\n break;\n default:\n console.warn(`unexpected scroll request ${scrollRequest[\"type\"]}`);\n }\n }\n },\n [\n appliedPageSize,\n isVirtualScroll,\n onVerticalScrollInSitu,\n rowHeight,\n setRange,\n totalHeaderHeight,\n viewportBodyHeight,\n viewportRowCount,\n ],\n );\n\n const scrollHandles: ScrollingAPI = useMemo(\n // TODO not complete yet\n () => ({\n scrollToIndex: (rowIndex: number) => {\n if (scrollbarContainerRef.current) {\n // TODO hardcoded rowHeight\n const scrollPos = (rowIndex - 30) * 20;\n scrollbarContainerRef.current.scrollTop = scrollPos;\n }\n },\n scrollToKey: (rowKey: string) => {\n console.log(`scrollToKey ${rowKey}`);\n },\n }),\n [],\n );\n\n useImperativeHandle(scrollingApiRef, () => {\n if (scrollbarContainerRef.current) {\n return scrollHandles;\n } else {\n return noScrolling;\n }\n }, [scrollHandles]);\n\n useEffect(() => {\n if (rowHeight !== rowHeightRef.current) {\n rowHeightRef.current = rowHeight;\n if (contentContainerPosRef.current.scrollTop > 0) {\n if (contentContainerRef.current) {\n contentContainerRef.current.scrollTop = 0;\n }\n }\n } else if (usesMeasuredHeaderHeight) {\n const { current: from } = firstRowRef;\n const rowRange = { from, to: from + viewportRowCount };\n setRange(rowRange);\n }\n }, [rowHeight, setRange, usesMeasuredHeaderHeight, viewportRowCount]);\n\n return {\n columnsWithinViewport: columnsWithinViewportRef.current,\n /** Ref to be assigned to ScrollbarContainer */\n scrollbarContainerRef: scrollbarContainerCallbackRef,\n /** Ref to be assigned to ContentContainer */\n contentContainerRef: contentContainerCallbackRef,\n /** Scroll the table */\n requestScroll,\n scrollTop: contentContainerPosRef.current.scrollTop,\n /** number of leading columns not rendered because of virtualization */\n virtualColSpan: preSpanRef.current,\n };\n};\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,22 +1,22 @@
1
1
  {
2
- "version": "0.13.113-alpha.2",
2
+ "version": "0.13.114",
3
3
  "author": "heswell",
4
4
  "license": "Apache-2.0",
5
5
  "devDependencies": {
6
- "@vuu-ui/vuu-data-types": "0.13.113-alpha.2",
7
- "@vuu-ui/vuu-table-types": "0.13.113-alpha.2",
8
- "@vuu-ui/vuu-protocol-types": "0.13.113-alpha.2"
6
+ "@vuu-ui/vuu-data-types": "0.13.114",
7
+ "@vuu-ui/vuu-table-types": "0.13.114",
8
+ "@vuu-ui/vuu-protocol-types": "0.13.114"
9
9
  },
10
10
  "dependencies": {
11
11
  "@salt-ds/core": "1.54.1",
12
12
  "@salt-ds/styles": "0.2.1",
13
13
  "@salt-ds/window": "0.1.1",
14
- "@vuu-ui/vuu-context-menu": "0.13.113-alpha.2",
15
- "@vuu-ui/vuu-data-react": "0.13.113-alpha.2",
16
- "@vuu-ui/vuu-popups": "0.13.113-alpha.2",
17
- "@vuu-ui/vuu-table-extras": "0.13.113-alpha.2",
18
- "@vuu-ui/vuu-ui-controls": "0.13.113-alpha.2",
19
- "@vuu-ui/vuu-utils": "0.13.113-alpha.2"
14
+ "@vuu-ui/vuu-context-menu": "0.13.114",
15
+ "@vuu-ui/vuu-data-react": "0.13.114",
16
+ "@vuu-ui/vuu-popups": "0.13.114",
17
+ "@vuu-ui/vuu-table-extras": "0.13.114",
18
+ "@vuu-ui/vuu-ui-controls": "0.13.114",
19
+ "@vuu-ui/vuu-utils": "0.13.114"
20
20
  },
21
21
  "peerDependencies": {
22
22
  "clsx": "^2.0.0",