Skip to content

Commit faf5ffb

Browse files
committed
Unified UnitKeyboardSelection
1 parent d9c959d commit faf5ffb

File tree

2 files changed

+38
-33
lines changed

2 files changed

+38
-33
lines changed

packages/column-views/src/correlation-chart/main.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import {
44
UnitKeyboardNavigation,
55
useUnitSelectionDispatch,
66
useColumnRef,
7-
CorrelationChartKeyboardNavigation,
87
} from "../data-provider";
98
import { UnitDetailsFeature, UnitSelectionPopover } from "../unit-details";
109
import hyper from "@macrostrat/hyper";
@@ -149,7 +148,7 @@ export function CorrelationChart({
149148
features: unitPopoverFeatures,
150149
}),
151150
// Navigation only works within a column for now...
152-
h(CorrelationChartKeyboardNavigation, { columnData: data }),
151+
h(UnitKeyboardNavigation, { columnData: data }),
153152
]),
154153
]),
155154
),

packages/column-views/src/data-provider/unit-selection.ts

Lines changed: 37 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { BaseUnit, UnitLong } from "@macrostrat/api-types";
22
import { useKeyHandler } from "@macrostrat/ui-components";
3-
import { useEffect, useRef, useCallback } from "react";
3+
import { useEffect, useRef, useCallback, useMemo } from "react";
44
import type { RectBounds, IUnit } from "../units/types";
55
import { atom } from "jotai";
66
import { columnUnitsMapAtom, scope } from "./core";
@@ -179,58 +179,64 @@ export function useUnitSelectionTarget(
179179
return [ref, selected, onClick];
180180
}
181181

182-
export function UnitKeyboardNavigation<T extends BaseUnit>({
182+
export function UnitKeyboardNavigation({
183+
columnData,
183184
units,
185+
allowHorizontalNavigation,
184186
}: {
185-
units: T[];
187+
columnData?: ColumnData[];
188+
units?: UnitLong[];
189+
allowHorizontalNavigation?: boolean;
186190
}) {
187-
const selectedUnit = useSelectedUnit();
188-
const selectUnit = useUnitSelectionDispatch();
189-
190-
const ix = units.findIndex((unit) => unit.unit_id === selectedUnit?.unit_id);
191+
if (units == null && columnData == null) {
192+
throw new Error("Either units or columnData must be provided.");
193+
}
191194

192-
const keyMap = {
193-
38: ix - 1,
194-
40: ix + 1,
195-
};
195+
let _columnData: ColumnData[] = useMemo(() => {
196+
if (columnData != null) return columnData;
197+
// Build column data from units
198+
const colMap = new Map<number, UnitLong[]>();
199+
for (const unit of units!) {
200+
if (!colMap.has(unit.col_id)) {
201+
colMap.set(unit.col_id, []);
202+
}
203+
colMap.get(unit.col_id)!.push(unit);
204+
}
205+
const cols: ColumnData[] = [];
206+
for (const [colID, units] of colMap) {
207+
cols.push({ columnID: colID, units });
208+
}
209+
// Sort columns by columnID
210+
cols.sort((a, b) => a.columnID - b.columnID);
211+
return cols;
212+
}, [columnData, units]);
196213

197-
useKeyHandler(
198-
(event) => {
199-
const nextIx = keyMap[event.keyCode];
200-
if (nextIx == null || nextIx < 0 || nextIx >= units.length) return;
201-
selectUnit(units[nextIx], null);
202-
event.stopPropagation();
203-
},
204-
[units, ix],
205-
);
206-
return null;
207-
}
214+
// Default to allowing horizontal navigation only if columnData is provided
215+
const _allowHorizontalNavigation =
216+
allowHorizontalNavigation ?? columnData != null;
208217

209-
export function CorrelationChartKeyboardNavigation({
210-
columnData,
211-
}: {
212-
columnData: ColumnData[];
213-
}) {
214218
const selectedUnit = useSelectedUnit() as UnitLong | null;
215219
const selectUnit = useUnitSelectionDispatch();
216220

217221
const keyMap: Record<number, Direction> = {
218-
37: "left",
219222
38: "up",
220-
39: "right",
221223
40: "down",
222224
};
225+
if (_allowHorizontalNavigation) {
226+
keyMap[37] = "left";
227+
keyMap[39] = "right";
228+
}
223229

224230
useKeyHandler(
225231
(event) => {
226232
const direction = keyMap[event.keyCode];
227233
if (direction == null) return;
228-
const nextUnit = getBestUnit(columnData, selectedUnit, direction);
234+
const nextUnit = getBestUnit(_columnData, selectedUnit, direction);
229235
if (nextUnit == null) return;
230236
selectUnit(nextUnit, null);
231237
event.stopPropagation();
232238
},
233-
[selectedUnit],
239+
[_columnData, selectedUnit],
234240
);
235241
return null;
236242
}

0 commit comments

Comments
 (0)