@macrostrat/column-views 2.3.3 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/dist/esm/{column-views.ce3a3ac8.js → column-views.0f910df6.js} +2 -2
- package/dist/esm/{column-views.ce3a3ac8.js.map → column-views.0f910df6.js.map} +1 -1
- package/dist/esm/{column-views.4e6eead3.js → column-views.1cd57b96.js} +2 -2
- package/dist/esm/{column-views.4e6eead3.js.map → column-views.1cd57b96.js.map} +1 -1
- package/dist/esm/{column-views.ee9d71ba.js → column-views.1d356b7e.js} +2 -2
- package/dist/esm/{column-views.ee9d71ba.js.map → column-views.1d356b7e.js.map} +1 -1
- package/dist/esm/{column-views.3d3e00be.js → column-views.1ef0f7e8.js} +2 -2
- package/dist/esm/{column-views.3d3e00be.js.map → column-views.1ef0f7e8.js.map} +1 -1
- package/dist/esm/{column-views.ad2fe46c.js → column-views.1f954206.js} +2 -2
- package/dist/esm/{column-views.ad2fe46c.js.map → column-views.1f954206.js.map} +1 -1
- package/dist/esm/{column-views.24060b85.js → column-views.25713aad.js} +4 -4
- package/dist/esm/{column-views.24060b85.js.map → column-views.25713aad.js.map} +1 -1
- package/dist/esm/{column-views.9ffc089b.js → column-views.28cab78c.js} +3 -3
- package/dist/esm/{column-views.9ffc089b.js.map → column-views.28cab78c.js.map} +1 -1
- package/dist/esm/column-views.2e517e39.js +126 -0
- package/dist/esm/column-views.2e517e39.js.map +1 -0
- package/dist/esm/{column-views.18aac6a5.js → column-views.3067c5e3.js} +3 -3
- package/dist/esm/{column-views.18aac6a5.js.map → column-views.3067c5e3.js.map} +1 -1
- package/dist/esm/{column-views.6f96d1c3.js → column-views.31152763.js} +20 -17
- package/dist/esm/column-views.31152763.js.map +1 -0
- package/dist/esm/{column-views.04636815.js → column-views.33daabd5.js} +5 -5
- package/dist/esm/{column-views.04636815.js.map → column-views.33daabd5.js.map} +1 -1
- package/dist/esm/{column-views.e075af15.js → column-views.3c1cde51.js} +2 -2
- package/dist/esm/{column-views.e075af15.js.map → column-views.3c1cde51.js.map} +1 -1
- package/dist/esm/{column-views.0da4503a.js → column-views.3c9f5ba9.js} +2 -2
- package/dist/esm/{column-views.0da4503a.js.map → column-views.3c9f5ba9.js.map} +1 -1
- package/dist/esm/{column-views.c149f7a5.js → column-views.3d33ef0f.js} +3 -3
- package/dist/esm/{column-views.c149f7a5.js.map → column-views.3d33ef0f.js.map} +1 -1
- package/dist/esm/{column-views.8d972657.js → column-views.4099a246.js} +3 -3
- package/dist/esm/{column-views.8d972657.js.map → column-views.4099a246.js.map} +1 -1
- package/dist/esm/{column-views.b9265595.js → column-views.45acb682.js} +6 -6
- package/dist/esm/column-views.45acb682.js.map +1 -0
- package/dist/esm/{column-views.26e0e0b6.js → column-views.4e5746da.js} +2 -2
- package/dist/esm/{column-views.26e0e0b6.js.map → column-views.4e5746da.js.map} +1 -1
- package/dist/esm/{column-views.f7cdf6be.js → column-views.55bce35c.js} +3 -3
- package/dist/esm/{column-views.f7cdf6be.js.map → column-views.55bce35c.js.map} +1 -1
- package/dist/esm/{column-views.029ea8f1.js → column-views.631f55d4.js} +3 -3
- package/dist/esm/{column-views.029ea8f1.js.map → column-views.631f55d4.js.map} +1 -1
- package/dist/esm/column-views.67804ce5.js +68 -0
- package/dist/esm/column-views.67804ce5.js.map +1 -0
- package/dist/esm/column-views.8168c37d.js +113 -0
- package/dist/esm/column-views.8168c37d.js.map +1 -0
- package/dist/esm/{column-views.b977da35.js → column-views.848349c0.js} +5 -5
- package/dist/esm/{column-views.b977da35.js.map → column-views.848349c0.js.map} +1 -1
- package/dist/esm/{column-views.73fc96cb.js → column-views.86b879ba.js} +5 -5
- package/dist/esm/{column-views.73fc96cb.js.map → column-views.86b879ba.js.map} +1 -1
- package/dist/esm/{column-views.d6c0b7bc.js → column-views.8c8f3fe0.js} +2 -2
- package/dist/esm/{column-views.d6c0b7bc.js.map → column-views.8c8f3fe0.js.map} +1 -1
- package/dist/esm/{column-views.3f1cdc18.js → column-views.9b210fb2.js} +2 -2
- package/dist/esm/{column-views.3f1cdc18.js.map → column-views.9b210fb2.js.map} +1 -1
- package/dist/esm/{column-views.4685ea28.js → column-views.9d0d78aa.js} +2 -2
- package/dist/esm/{column-views.4685ea28.js.map → column-views.9d0d78aa.js.map} +1 -1
- package/dist/esm/{column-views.e3f0cd7b.js → column-views.af89f2b1.js} +23 -33
- package/dist/esm/column-views.af89f2b1.js.map +1 -0
- package/dist/esm/{column-views.75b83110.js → column-views.b3398cca.js} +5 -5
- package/dist/esm/{column-views.75b83110.js.map → column-views.b3398cca.js.map} +1 -1
- package/dist/esm/{column-views.2f979aee.js → column-views.b7b0be88.js} +3 -3
- package/dist/esm/{column-views.2f979aee.js.map → column-views.b7b0be88.js.map} +1 -1
- package/dist/esm/{column-views.d1b49f5c.js → column-views.b8933ea2.js} +2 -2
- package/dist/esm/{column-views.d1b49f5c.js.map → column-views.b8933ea2.js.map} +1 -1
- package/dist/esm/{column-views.0a010643.js → column-views.b9c4d94c.js} +4 -4
- package/dist/esm/{column-views.0a010643.js.map → column-views.b9c4d94c.js.map} +1 -1
- package/dist/esm/{column-views.5fff0716.js → column-views.d3a4596e.js} +3 -3
- package/dist/esm/{column-views.5fff0716.js.map → column-views.d3a4596e.js.map} +1 -1
- package/dist/esm/{column-views.d5fff9b8.js → column-views.dda76243.js} +3 -3
- package/dist/esm/{column-views.d5fff9b8.js.map → column-views.dda76243.js.map} +1 -1
- package/dist/esm/{column-views.9d51a5ab.js → column-views.df872a2c.js} +2 -2
- package/dist/esm/column-views.df872a2c.js.map +1 -0
- package/dist/esm/{column-views.488f24b6.js → column-views.e21f4e50.js} +2 -2
- package/dist/esm/{column-views.488f24b6.js.map → column-views.e21f4e50.js.map} +1 -1
- package/dist/esm/{column-views.a665cbb2.js → column-views.f046b170.js} +5 -5
- package/dist/esm/{column-views.a665cbb2.js.map → column-views.f046b170.js.map} +1 -1
- package/dist/esm/{column-views.82a5112b.js → column-views.fc4d28d8.js} +4 -4
- package/dist/esm/{column-views.82a5112b.js.map → column-views.fc4d28d8.js.map} +1 -1
- package/dist/esm/{column-views.faa7e52e.js → column-views.fdb3799c.js} +3 -3
- package/dist/esm/{column-views.faa7e52e.js.map → column-views.fdb3799c.js.map} +1 -1
- package/dist/esm/index.d.ts +73 -57
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +11 -11
- package/dist/node/{column-views.75456275.js → column-views.00c19fe8.js} +2 -2
- package/dist/node/{column-views.75456275.js.map → column-views.00c19fe8.js.map} +1 -1
- package/dist/node/{column-views.7c322202.js → column-views.00caa49a.js} +2 -2
- package/dist/node/{column-views.7c322202.js.map → column-views.00caa49a.js.map} +1 -1
- package/dist/node/{column-views.9efa91f1.js → column-views.07680def.js} +2 -2
- package/dist/node/{column-views.9efa91f1.js.map → column-views.07680def.js.map} +1 -1
- package/dist/node/column-views.0980c2a0.js +2 -0
- package/dist/node/column-views.0980c2a0.js.map +1 -0
- package/dist/node/column-views.1495397b.js +2 -0
- package/dist/node/column-views.1495397b.js.map +1 -0
- package/dist/node/{column-views.47440961.js → column-views.190241c4.js} +2 -2
- package/dist/node/{column-views.47440961.js.map → column-views.190241c4.js.map} +1 -1
- package/dist/node/{column-views.fafbc028.js → column-views.1d1d6117.js} +2 -2
- package/dist/node/{column-views.fafbc028.js.map → column-views.1d1d6117.js.map} +1 -1
- package/dist/node/column-views.26306041.js +2 -0
- package/dist/node/column-views.26306041.js.map +1 -0
- package/dist/node/{column-views.6556e004.js → column-views.3ce34544.js} +2 -2
- package/dist/node/{column-views.6556e004.js.map → column-views.3ce34544.js.map} +1 -1
- package/dist/node/{column-views.c007152b.js → column-views.41d72280.js} +2 -2
- package/dist/node/{column-views.c007152b.js.map → column-views.41d72280.js.map} +1 -1
- package/dist/node/{column-views.59ce629d.js → column-views.4e677bc4.js} +2 -2
- package/dist/node/{column-views.59ce629d.js.map → column-views.4e677bc4.js.map} +1 -1
- package/dist/node/{column-views.2fe8feb9.js → column-views.60dc38f3.js} +2 -2
- package/dist/node/{column-views.2fe8feb9.js.map → column-views.60dc38f3.js.map} +1 -1
- package/dist/node/{column-views.d818b387.js → column-views.68fe4814.js} +2 -2
- package/dist/node/{column-views.d818b387.js.map → column-views.68fe4814.js.map} +1 -1
- package/dist/node/{column-views.3a947d58.js → column-views.69ddf14d.js} +2 -2
- package/dist/node/{column-views.3a947d58.js.map → column-views.69ddf14d.js.map} +1 -1
- package/dist/node/column-views.6d6a8fde.js +2 -0
- package/dist/node/column-views.6d6a8fde.js.map +1 -0
- package/dist/node/{column-views.08bef1f6.js → column-views.705f66b1.js} +2 -2
- package/dist/node/{column-views.08bef1f6.js.map → column-views.705f66b1.js.map} +1 -1
- package/dist/node/{column-views.8e846c57.js → column-views.7714173b.js} +2 -2
- package/dist/node/{column-views.8e846c57.js.map → column-views.7714173b.js.map} +1 -1
- package/dist/node/{column-views.a14f0134.js → column-views.7ee01d2b.js} +2 -2
- package/dist/node/{column-views.a14f0134.js.map → column-views.7ee01d2b.js.map} +1 -1
- package/dist/node/column-views.861b8e3e.js +2 -0
- package/dist/node/column-views.861b8e3e.js.map +1 -0
- package/dist/node/{column-views.c921fa1a.js → column-views.89afd6b3.js} +2 -2
- package/dist/node/{column-views.c921fa1a.js.map → column-views.89afd6b3.js.map} +1 -1
- package/dist/node/{column-views.8eae7028.js → column-views.8f5532b0.js} +2 -2
- package/dist/node/{column-views.8eae7028.js.map → column-views.8f5532b0.js.map} +1 -1
- package/dist/node/{column-views.67e7a200.js → column-views.97f7f353.js} +2 -2
- package/dist/node/{column-views.67e7a200.js.map → column-views.97f7f353.js.map} +1 -1
- package/dist/node/{column-views.3d0c2bea.js → column-views.9a408bbf.js} +2 -2
- package/dist/node/{column-views.3d0c2bea.js.map → column-views.9a408bbf.js.map} +1 -1
- package/dist/node/column-views.a0969fc8.js +2 -0
- package/dist/node/column-views.a0969fc8.js.map +1 -0
- package/dist/node/{column-views.02869dc5.js → column-views.a0e23210.js} +2 -2
- package/dist/node/{column-views.02869dc5.js.map → column-views.a0e23210.js.map} +1 -1
- package/dist/node/{column-views.8f540f78.js → column-views.a54c0820.js} +2 -2
- package/dist/node/{column-views.8f540f78.js.map → column-views.a54c0820.js.map} +1 -1
- package/dist/node/{column-views.0f401891.js → column-views.b3aa406d.js} +2 -2
- package/dist/node/{column-views.0f401891.js.map → column-views.b3aa406d.js.map} +1 -1
- package/dist/node/{column-views.0a2596c2.js → column-views.b7f69f19.js} +2 -2
- package/dist/node/{column-views.0a2596c2.js.map → column-views.b7f69f19.js.map} +1 -1
- package/dist/node/{column-views.cd54f1b1.js → column-views.b9900855.js} +2 -2
- package/dist/node/{column-views.cd54f1b1.js.map → column-views.b9900855.js.map} +1 -1
- package/dist/node/{column-views.6b391d60.js → column-views.bd1481f0.js} +2 -2
- package/dist/node/{column-views.6b391d60.js.map → column-views.bd1481f0.js.map} +1 -1
- package/dist/node/{column-views.e264a767.js → column-views.bf90c8a3.js} +2 -2
- package/dist/node/column-views.bf90c8a3.js.map +1 -0
- package/dist/node/{column-views.fee4e65d.js → column-views.bfaf5ddb.js} +2 -2
- package/dist/node/{column-views.fee4e65d.js.map → column-views.bfaf5ddb.js.map} +1 -1
- package/dist/node/{column-views.00ad98fa.js → column-views.dedafcae.js} +2 -2
- package/dist/node/{column-views.00ad98fa.js.map → column-views.dedafcae.js.map} +1 -1
- package/dist/node/{column-views.e153680b.js → column-views.e1481ea6.js} +2 -2
- package/dist/node/{column-views.e153680b.js.map → column-views.e1481ea6.js.map} +1 -1
- package/dist/node/{column-views.c4188442.js → column-views.e4e014cd.js} +2 -2
- package/dist/node/{column-views.c4188442.js.map → column-views.e4e014cd.js.map} +1 -1
- package/dist/node/{column-views.465e593b.js → column-views.ed7b4c16.js} +2 -2
- package/dist/node/{column-views.465e593b.js.map → column-views.ed7b4c16.js.map} +1 -1
- package/dist/node/{column-views.2577dec0.js → column-views.f749dbd6.js} +2 -2
- package/dist/node/{column-views.2577dec0.js.map → column-views.f749dbd6.js.map} +1 -1
- package/dist/node/{column-views.825d2719.js → column-views.fcf2be3c.js} +2 -2
- package/dist/node/{column-views.825d2719.js.map → column-views.fcf2be3c.js.map} +1 -1
- package/dist/node/index.js +1 -1
- package/dist/node/index.js.map +1 -1
- package/package.json +3 -2
- package/src/age-model-overlay.ts +4 -2
- package/src/column.ts +18 -41
- package/src/correlation-chart/main.ts +11 -9
- package/src/data-provider/core.ts +89 -0
- package/src/data-provider/store.ts +79 -88
- package/src/data-provider/unit-selection.ts +120 -147
- package/src/unit-details/popover.ts +8 -4
- package/dist/esm/column-views.4b259f9e.js +0 -136
- package/dist/esm/column-views.4b259f9e.js.map +0 -1
- package/dist/esm/column-views.6f96d1c3.js.map +0 -1
- package/dist/esm/column-views.9d51a5ab.js.map +0 -1
- package/dist/esm/column-views.b9265595.js.map +0 -1
- package/dist/esm/column-views.c44febd0.js +0 -169
- package/dist/esm/column-views.c44febd0.js.map +0 -1
- package/dist/esm/column-views.e3f0cd7b.js.map +0 -1
- package/dist/node/column-views.0beae29d.js +0 -2
- package/dist/node/column-views.0beae29d.js.map +0 -1
- package/dist/node/column-views.46efb749.js +0 -2
- package/dist/node/column-views.46efb749.js.map +0 -1
- package/dist/node/column-views.868c04dc.js +0 -2
- package/dist/node/column-views.868c04dc.js.map +0 -1
- package/dist/node/column-views.dfe9a971.js +0 -2
- package/dist/node/column-views.dfe9a971.js.map +0 -1
- package/dist/node/column-views.e264a767.js.map +0 -1
- package/dist/node/column-views.ed2fd268.js +0 -2
- package/dist/node/column-views.ed2fd268.js.map +0 -1
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { atom, type WritableAtom } from "jotai";
|
|
2
|
+
import { createIsolation } from "jotai-scope";
|
|
3
|
+
import { BaseUnit } from "@macrostrat/api-types";
|
|
4
|
+
import { ReactNode, useEffect, useRef } from "react";
|
|
5
|
+
import h from "@macrostrat/hyper";
|
|
6
|
+
|
|
7
|
+
interface StateIsolation {
|
|
8
|
+
Provider: (props: {
|
|
9
|
+
store?: any;
|
|
10
|
+
initialValues?: AtomMap;
|
|
11
|
+
children: ReactNode;
|
|
12
|
+
}) => ReactNode;
|
|
13
|
+
useStore: () => any;
|
|
14
|
+
useAtom: any;
|
|
15
|
+
useAtomValue: any;
|
|
16
|
+
useSetAtom: any;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export const scope: StateIsolation = createIsolation();
|
|
20
|
+
|
|
21
|
+
export type AtomMap = [WritableAtom<any, any, any>, any][];
|
|
22
|
+
|
|
23
|
+
type ProviderProps = {
|
|
24
|
+
children: ReactNode;
|
|
25
|
+
atoms?: AtomMap;
|
|
26
|
+
shouldUpdateAtoms?: boolean;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export function ScopedProvider({
|
|
30
|
+
children,
|
|
31
|
+
atoms,
|
|
32
|
+
shouldUpdateAtoms = true,
|
|
33
|
+
}: ProviderProps) {
|
|
34
|
+
// Always use the same store instance in this tree
|
|
35
|
+
let val = null;
|
|
36
|
+
try {
|
|
37
|
+
val = scope.useStore();
|
|
38
|
+
// This store has already been provided
|
|
39
|
+
return children;
|
|
40
|
+
} catch {
|
|
41
|
+
return h(scope.Provider, { store: null, initialValues: atoms }, [
|
|
42
|
+
h.if(shouldUpdateAtoms)(AtomUpdater, { atoms }),
|
|
43
|
+
children,
|
|
44
|
+
]);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function AtomUpdater({
|
|
49
|
+
atoms,
|
|
50
|
+
}: {
|
|
51
|
+
atoms: [WritableAtom<any, any, any>, any][];
|
|
52
|
+
}) {
|
|
53
|
+
/**
|
|
54
|
+
* A generic updater to sync Jotai atoms with state passed as props.
|
|
55
|
+
* Useful for scoped providers where state needs to be synced outside
|
|
56
|
+
* the current context.
|
|
57
|
+
*/
|
|
58
|
+
/** TODO: this is an awkward way to keep atoms updated */
|
|
59
|
+
// The scoped store
|
|
60
|
+
const store = scope.useStore();
|
|
61
|
+
|
|
62
|
+
// Warn on atoms changing length
|
|
63
|
+
const prevLengthRef = useRef(atoms.length);
|
|
64
|
+
useEffect(() => {
|
|
65
|
+
if (prevLengthRef.current !== atoms.length) {
|
|
66
|
+
console.error("Error: number of atoms in ScopedAtomUpdater has changed.");
|
|
67
|
+
prevLengthRef.current = atoms.length;
|
|
68
|
+
}
|
|
69
|
+
}, [atoms.length]);
|
|
70
|
+
|
|
71
|
+
for (const [atom, value] of atoms) {
|
|
72
|
+
useEffect(() => {
|
|
73
|
+
store.set(atom, value);
|
|
74
|
+
}, [store, value]);
|
|
75
|
+
}
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export const columnUnitsAtom = atom<BaseUnit[]>();
|
|
80
|
+
|
|
81
|
+
export const columnUnitsMapAtom = atom<Map<number, BaseUnit> | null>((get) => {
|
|
82
|
+
const units = get(columnUnitsAtom);
|
|
83
|
+
if (!units) return null;
|
|
84
|
+
const unitMap = new Map<number, BaseUnit>();
|
|
85
|
+
units.forEach((unit) => {
|
|
86
|
+
unitMap.set(unit.unit_id, unit);
|
|
87
|
+
});
|
|
88
|
+
return unitMap;
|
|
89
|
+
});
|
|
@@ -1,11 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
createContext,
|
|
3
|
-
ReactNode,
|
|
4
|
-
useContext,
|
|
5
|
-
useEffect,
|
|
6
|
-
useMemo,
|
|
7
|
-
useRef,
|
|
8
|
-
} from "react";
|
|
1
|
+
import { createContext, ReactNode, useContext, useMemo } from "react";
|
|
9
2
|
import h from "@macrostrat/hyper";
|
|
10
3
|
import {
|
|
11
4
|
CompositeColumnScale,
|
|
@@ -13,84 +6,98 @@ import {
|
|
|
13
6
|
} from "../prepare-units/composite-scale";
|
|
14
7
|
import { ColumnAxisType } from "@macrostrat/column-components";
|
|
15
8
|
import type { ExtUnit, PackageLayoutData } from "../prepare-units";
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
9
|
+
import {
|
|
10
|
+
allowUnitSelectionAtom,
|
|
11
|
+
selectedUnitIDAtom,
|
|
12
|
+
UnitSelectionCallbacks,
|
|
13
|
+
UnitSelectionCallbackManager,
|
|
14
|
+
} from "./unit-selection";
|
|
15
|
+
import { BaseUnit } from "@macrostrat/api-types";
|
|
16
|
+
import {
|
|
17
|
+
AtomMap,
|
|
18
|
+
columnUnitsAtom,
|
|
19
|
+
columnUnitsMapAtom,
|
|
20
|
+
scope,
|
|
21
|
+
ScopedProvider,
|
|
22
|
+
} from "./core";
|
|
23
|
+
|
|
24
|
+
export interface ColumnStateProviderProps<
|
|
25
|
+
T extends BaseUnit,
|
|
26
|
+
> extends Partial<UnitSelectionCallbacks> {
|
|
24
27
|
children: ReactNode;
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
const columnUnitsAtom = atom<ExtUnit[]>();
|
|
29
|
-
|
|
30
|
-
const columnUnitsMapAtom = atom<Map<number, ExtUnit> | null>((get) => {
|
|
31
|
-
const units = get(columnUnitsAtom);
|
|
32
|
-
if (!units) return null;
|
|
33
|
-
const unitMap = new Map<number, ExtUnit>();
|
|
34
|
-
units.forEach((unit) => {
|
|
35
|
-
unitMap.set(unit.unit_id, unit);
|
|
36
|
-
});
|
|
37
|
-
return unitMap;
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
function ScopedProvider({ children, ...rest }: ProviderProps) {
|
|
41
|
-
// Always use the same store instance in this tree
|
|
42
|
-
let val = null;
|
|
43
|
-
try {
|
|
44
|
-
val = useStore();
|
|
45
|
-
} catch {
|
|
46
|
-
// No store found, create a new one
|
|
47
|
-
val = null;
|
|
48
|
-
}
|
|
49
|
-
return h(Provider, { store: val, ...rest }, children);
|
|
28
|
+
units: T[];
|
|
29
|
+
selectedUnit: number | null;
|
|
30
|
+
allowUnitSelection?: boolean;
|
|
50
31
|
}
|
|
51
32
|
|
|
52
|
-
export function MacrostratColumnStateProvider({
|
|
33
|
+
export function MacrostratColumnStateProvider<T extends BaseUnit>({
|
|
53
34
|
children,
|
|
54
35
|
units,
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
}) {
|
|
36
|
+
allowUnitSelection = false,
|
|
37
|
+
onUnitSelected,
|
|
38
|
+
selectedUnit,
|
|
39
|
+
}: ColumnStateProviderProps<T>) {
|
|
59
40
|
/** Top-level provider for Macrostrat column data.
|
|
60
41
|
* It is either provided by the Column component itself, or
|
|
61
42
|
* can be hoisted higher in the tree to provide a common data context
|
|
62
43
|
*/
|
|
63
44
|
|
|
64
|
-
|
|
45
|
+
/* By default, unit selection is disabled. However, if any related props are passed,
|
|
46
|
+
we enable it.
|
|
47
|
+
*/
|
|
48
|
+
const _allowSelection = useMemo(() => {
|
|
49
|
+
if (allowUnitSelection) {
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
return selectedUnit != null || onUnitSelected != null;
|
|
53
|
+
}, []);
|
|
54
|
+
|
|
55
|
+
const atomMap: AtomMap = [
|
|
65
56
|
[columnUnitsAtom, units],
|
|
57
|
+
[allowUnitSelectionAtom, _allowSelection],
|
|
58
|
+
[selectedUnitIDAtom, selectedUnit],
|
|
66
59
|
];
|
|
67
60
|
|
|
61
|
+
let selectionHandlers: ReactNode = null;
|
|
62
|
+
if (_allowSelection) {
|
|
63
|
+
selectionHandlers = h(UnitSelectionCallbackManager, { onUnitSelected });
|
|
64
|
+
}
|
|
65
|
+
|
|
68
66
|
return h(
|
|
69
67
|
ScopedProvider,
|
|
70
68
|
{
|
|
71
|
-
|
|
69
|
+
atoms: atomMap,
|
|
72
70
|
},
|
|
73
|
-
[
|
|
71
|
+
[selectionHandlers, children],
|
|
74
72
|
);
|
|
75
73
|
}
|
|
76
74
|
|
|
77
|
-
export interface MacrostratColumnDataContext {
|
|
78
|
-
units:
|
|
75
|
+
export interface MacrostratColumnDataContext<T extends BaseUnit> {
|
|
76
|
+
units: T[];
|
|
79
77
|
sections: PackageLayoutData[];
|
|
80
78
|
totalHeight?: number;
|
|
81
79
|
axisType?: ColumnAxisType;
|
|
80
|
+
allowUnitSelection?: boolean;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export interface ColumnDataProviderProps<T extends BaseUnit>
|
|
84
|
+
extends MacrostratColumnDataContext<T>, ColumnStateProviderProps<T> {
|
|
85
|
+
children: ReactNode;
|
|
82
86
|
}
|
|
83
87
|
|
|
84
88
|
const MacrostratColumnDataContext =
|
|
85
|
-
createContext<MacrostratColumnDataContext
|
|
89
|
+
createContext<MacrostratColumnDataContext<any>>(null);
|
|
86
90
|
|
|
87
|
-
export function MacrostratColumnDataProvider({
|
|
91
|
+
export function MacrostratColumnDataProvider<T extends BaseUnit>({
|
|
88
92
|
children,
|
|
89
93
|
units,
|
|
90
94
|
sections,
|
|
91
95
|
totalHeight,
|
|
92
96
|
axisType,
|
|
93
|
-
|
|
97
|
+
allowUnitSelection,
|
|
98
|
+
onUnitSelected,
|
|
99
|
+
selectedUnit,
|
|
100
|
+
}: ColumnDataProviderProps<T>) {
|
|
94
101
|
/** Internal provider for Macrostrat column data.
|
|
95
102
|
* As a general rule, we want to provide data and column-axis
|
|
96
103
|
* height calculations through the context, since these need to
|
|
@@ -114,11 +121,26 @@ export function MacrostratColumnDataProvider({
|
|
|
114
121
|
|
|
115
122
|
return h(
|
|
116
123
|
MacrostratColumnStateProvider,
|
|
117
|
-
{
|
|
124
|
+
{
|
|
125
|
+
units,
|
|
126
|
+
allowUnitSelection,
|
|
127
|
+
onUnitSelected,
|
|
128
|
+
selectedUnit,
|
|
129
|
+
},
|
|
118
130
|
h(MacrostratColumnDataContext.Provider, { value }, children),
|
|
119
131
|
);
|
|
120
132
|
}
|
|
121
133
|
|
|
134
|
+
export function UnitSelectionProvider(props: ColumnStateProviderProps<any>) {
|
|
135
|
+
/* A basic unit selection provider without column data context.
|
|
136
|
+
Mostly for use with the CorrelationChart component.
|
|
137
|
+
*/
|
|
138
|
+
return h(MacrostratColumnStateProvider, {
|
|
139
|
+
...props,
|
|
140
|
+
allowUnitSelection: true,
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
|
|
122
144
|
export function useMacrostratColumnData() {
|
|
123
145
|
const ctx = useContext(MacrostratColumnDataContext);
|
|
124
146
|
if (!ctx) {
|
|
@@ -130,12 +152,12 @@ export function useMacrostratColumnData() {
|
|
|
130
152
|
}
|
|
131
153
|
|
|
132
154
|
export function useMacrostratUnits() {
|
|
133
|
-
return useAtomValue(columnUnitsAtom);
|
|
155
|
+
return scope.useAtomValue(columnUnitsAtom);
|
|
134
156
|
}
|
|
135
157
|
|
|
136
158
|
export function useColumnUnitsMap(): Map<number, ExtUnit> | null {
|
|
137
159
|
try {
|
|
138
|
-
return useAtomValue(columnUnitsMapAtom)
|
|
160
|
+
return scope.useAtomValue(columnUnitsMapAtom) as Map<number, ExtUnit>;
|
|
139
161
|
} catch {
|
|
140
162
|
return null;
|
|
141
163
|
}
|
|
@@ -148,34 +170,3 @@ export function useCompositeScale(): CompositeColumnScale {
|
|
|
148
170
|
[ctx.sections],
|
|
149
171
|
);
|
|
150
172
|
}
|
|
151
|
-
|
|
152
|
-
function AtomUpdater({
|
|
153
|
-
atoms,
|
|
154
|
-
}: {
|
|
155
|
-
atoms: [WritableAtom<any, any, any>, any][];
|
|
156
|
-
}) {
|
|
157
|
-
/**
|
|
158
|
-
* A generic updater to sync Jotai atoms with state passed as props.
|
|
159
|
-
* Useful for scoped providers where state needs to be synced outside
|
|
160
|
-
* of the current context.
|
|
161
|
-
*/
|
|
162
|
-
/** TODO: this is an awkward way to keep atoms updated */
|
|
163
|
-
// The scoped store
|
|
164
|
-
const store = useStore();
|
|
165
|
-
|
|
166
|
-
// Warn on atoms changing length
|
|
167
|
-
const prevLengthRef = useRef(atoms.length);
|
|
168
|
-
useEffect(() => {
|
|
169
|
-
if (prevLengthRef.current !== atoms.length) {
|
|
170
|
-
console.error("Error: number of atoms in ScopedAtomUpdater has changed.");
|
|
171
|
-
prevLengthRef.current = atoms.length;
|
|
172
|
-
}
|
|
173
|
-
}, [atoms.length]);
|
|
174
|
-
|
|
175
|
-
for (const [atom, value] of atoms) {
|
|
176
|
-
useEffect(() => {
|
|
177
|
-
store.set(atom, value);
|
|
178
|
-
}, [store, value]);
|
|
179
|
-
}
|
|
180
|
-
return null;
|
|
181
|
-
}
|
|
@@ -1,55 +1,21 @@
|
|
|
1
1
|
import { BaseUnit } from "@macrostrat/api-types";
|
|
2
|
-
import h from "@macrostrat/hyper";
|
|
3
2
|
import { useKeyHandler } from "@macrostrat/ui-components";
|
|
4
|
-
import {
|
|
5
|
-
createContext,
|
|
6
|
-
useContext,
|
|
7
|
-
useEffect,
|
|
8
|
-
useState,
|
|
9
|
-
ReactNode,
|
|
10
|
-
RefObject,
|
|
11
|
-
useRef,
|
|
12
|
-
useCallback,
|
|
13
|
-
} from "react";
|
|
14
|
-
import { createStore, StoreApi, useStore } from "zustand";
|
|
3
|
+
import { useEffect, useRef, useCallback } from "react";
|
|
15
4
|
import type { RectBounds, IUnit } from "../units/types";
|
|
5
|
+
import { atom } from "jotai";
|
|
6
|
+
import { columnUnitsMapAtom, scope } from "./core";
|
|
16
7
|
|
|
17
8
|
type UnitSelectDispatch = (
|
|
18
9
|
unit: number | BaseUnit | null,
|
|
19
10
|
target: HTMLElement | null,
|
|
20
|
-
event: Event | null,
|
|
21
11
|
) => void;
|
|
22
12
|
|
|
23
|
-
const UnitSelectionContext = createContext<StoreApi<UnitSelectionStore>>(null);
|
|
24
|
-
|
|
25
13
|
export function useUnitSelectionDispatch(): UnitSelectDispatch {
|
|
26
|
-
|
|
27
|
-
if (store == null) {
|
|
28
|
-
return () => {};
|
|
29
|
-
}
|
|
30
|
-
return useStore(store, (state) => state.onUnitSelected);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export function useUnitSelectionStore<T>(
|
|
34
|
-
selector: (state: UnitSelectionStore) => T,
|
|
35
|
-
): T {
|
|
36
|
-
const store = useContext(UnitSelectionContext);
|
|
37
|
-
if (store == null) {
|
|
38
|
-
return null;
|
|
39
|
-
}
|
|
40
|
-
return useStore(store, selector);
|
|
14
|
+
return scope.useSetAtom(selectedUnitAtom);
|
|
41
15
|
}
|
|
42
16
|
|
|
43
17
|
export function useSelectedUnit() {
|
|
44
|
-
return
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
interface UnitSelectionStore {
|
|
48
|
-
selectedUnit: number | null;
|
|
49
|
-
selectedUnitData: BaseUnit | null;
|
|
50
|
-
overlayPosition: RectBounds | null;
|
|
51
|
-
onUnitSelected: UnitSelectDispatch;
|
|
52
|
-
setSelectedUnit: (unit: number | null) => void;
|
|
18
|
+
return scope.useAtomValue(selectedUnitAtom);
|
|
53
19
|
}
|
|
54
20
|
|
|
55
21
|
export interface ColumnClickData {
|
|
@@ -60,134 +26,141 @@ export interface ColumnClickData {
|
|
|
60
26
|
// Room for boundary IDs eventually
|
|
61
27
|
}
|
|
62
28
|
|
|
63
|
-
export
|
|
64
|
-
|
|
65
|
-
columnRef?: RefObject<HTMLElement>;
|
|
66
|
-
units: T[];
|
|
67
|
-
selectedUnit: number | null;
|
|
29
|
+
export interface UnitSelectionCallbacks {
|
|
30
|
+
// It's sort of unfortunate that we need to pass in the column ref here
|
|
68
31
|
onClickedColumn?: (columnClickData: ColumnClickData, event: Event) => void;
|
|
69
|
-
onUnitSelected?:
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
selectedUnitData: null,
|
|
75
|
-
overlayPosition: null,
|
|
76
|
-
setSelectedUnit(selectedUnit: number | null | BaseUnit) {
|
|
77
|
-
if (selectedUnit == null) {
|
|
78
|
-
set({ selectedUnit: null, selectedUnitData: null });
|
|
79
|
-
return;
|
|
80
|
-
// If it's a number, set the selected unit
|
|
81
|
-
} else if (typeof selectedUnit === "number") {
|
|
82
|
-
set({ selectedUnit, selectedUnitData: null });
|
|
83
|
-
} else if ("unit_id" in selectedUnit) {
|
|
84
|
-
set({
|
|
85
|
-
selectedUnit: selectedUnit.unit_id,
|
|
86
|
-
selectedUnitData: selectedUnit,
|
|
87
|
-
});
|
|
88
|
-
}
|
|
89
|
-
},
|
|
90
|
-
onUnitSelected: (
|
|
91
|
-
input: number | T | null,
|
|
92
|
-
target: HTMLElement = null,
|
|
93
|
-
event: PointerEvent = null,
|
|
94
|
-
) => {
|
|
95
|
-
if (input == null) {
|
|
96
|
-
props.onUnitSelected?.(null, null);
|
|
97
|
-
return set({
|
|
98
|
-
selectedUnit: null,
|
|
99
|
-
selectedUnitData: null,
|
|
100
|
-
overlayPosition: null,
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
let unit: T | null = null;
|
|
105
|
-
if (typeof input === "number") {
|
|
106
|
-
unit = props.units.find((u) => u.unit_id === input) || null;
|
|
107
|
-
} else {
|
|
108
|
-
unit = input;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
const el = props.columnRef?.current;
|
|
112
|
-
let overlayPosition = null;
|
|
113
|
-
|
|
114
|
-
/** This is not the natural place to get positions within the column,
|
|
115
|
-
* but it will work for now.
|
|
116
|
-
*/
|
|
117
|
-
if (props.onClickedColumn) {
|
|
118
|
-
// Infer height from top and bottom height of unit (because that's passed back with the call)
|
|
119
|
-
//const py = event.y;
|
|
120
|
-
//const [bottom, top] = getUnitHeightRange(unit, axisType);
|
|
121
|
-
//const height = Math.abs(bottom - top);
|
|
122
|
-
|
|
123
|
-
/** Ideally this would be defined at the column level */
|
|
124
|
-
const columnClickData: ColumnClickData = {
|
|
125
|
-
unitID: unit?.unit_id,
|
|
126
|
-
unit,
|
|
127
|
-
target,
|
|
128
|
-
height: el?.getBoundingClientRect().height || 0,
|
|
129
|
-
};
|
|
130
|
-
props.onClickedColumn(columnClickData, event);
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
if (unit != null && el != null && target != null) {
|
|
134
|
-
const rect = el.getBoundingClientRect();
|
|
135
|
-
const targetRect = target.getBoundingClientRect();
|
|
136
|
-
|
|
137
|
-
overlayPosition = {
|
|
138
|
-
x: targetRect.left - rect.left,
|
|
139
|
-
y: targetRect.top - rect.top,
|
|
140
|
-
width: targetRect.width,
|
|
141
|
-
height: targetRect.height,
|
|
142
|
-
};
|
|
143
|
-
}
|
|
144
|
-
props.onUnitSelected?.(unit?.unit_id, unit);
|
|
145
|
-
|
|
146
|
-
return set({
|
|
147
|
-
selectedUnit: unit?.unit_id,
|
|
148
|
-
selectedUnitData: unit,
|
|
149
|
-
overlayPosition,
|
|
150
|
-
});
|
|
151
|
-
},
|
|
152
|
-
})),
|
|
153
|
-
);
|
|
32
|
+
onUnitSelected?: <T extends BaseUnit>(
|
|
33
|
+
unitID: number | null,
|
|
34
|
+
unit: T | null,
|
|
35
|
+
) => void;
|
|
36
|
+
}
|
|
154
37
|
|
|
155
|
-
|
|
38
|
+
export const allowUnitSelectionAtom = atom<boolean>(true);
|
|
156
39
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
40
|
+
export const selectedUnitIDAtom = atom<number | null>();
|
|
41
|
+
|
|
42
|
+
const overlayPositionAtom = atom<RectBounds | null>();
|
|
43
|
+
|
|
44
|
+
const columnRefAtom = atom<{ current: HTMLElement | null }>({ current: null });
|
|
45
|
+
|
|
46
|
+
export function useColumnRef() {
|
|
47
|
+
return scope.useAtomValue(columnRefAtom);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const selectedUnitAtom = atom(
|
|
51
|
+
(get) => {
|
|
52
|
+
if (!get(allowUnitSelectionAtom)) return null;
|
|
53
|
+
|
|
54
|
+
const unitID = get(selectedUnitIDAtom);
|
|
55
|
+
if (unitID == null) return null;
|
|
56
|
+
const unitsMap = get(columnUnitsMapAtom);
|
|
57
|
+
return unitsMap?.get(unitID) || null;
|
|
58
|
+
},
|
|
59
|
+
(
|
|
60
|
+
get,
|
|
61
|
+
set,
|
|
62
|
+
selectedUnit: number | BaseUnit | null,
|
|
63
|
+
target: HTMLElement | null = null,
|
|
64
|
+
): BaseUnit | null => {
|
|
65
|
+
if (!get(allowUnitSelectionAtom)) {
|
|
66
|
+
throw new Error("Unit selection is disabled.");
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
let unitID: number | null;
|
|
70
|
+
let unit: BaseUnit | null = null;
|
|
71
|
+
if (selectedUnit == null) {
|
|
72
|
+
unitID = null;
|
|
73
|
+
} else if (typeof selectedUnit === "number") {
|
|
74
|
+
unitID = selectedUnit;
|
|
75
|
+
} else if ("unit_id" in selectedUnit) {
|
|
76
|
+
unitID = selectedUnit.unit_id;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (unitID != null) {
|
|
80
|
+
// Verify that the unit exists in the current colum, else throw
|
|
81
|
+
const unitsMap = get(columnUnitsMapAtom);
|
|
82
|
+
if (!unitsMap?.has(unitID)) {
|
|
83
|
+
throw new Error(
|
|
84
|
+
`Unit with ID ${unitID} not found in current column units.`,
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
unit = unitsMap.get(unitID) ?? null;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
let overlayPosition: RectBounds | null = null;
|
|
91
|
+
|
|
92
|
+
const columnEl = get(columnRefAtom)?.current;
|
|
93
|
+
|
|
94
|
+
if (unit != null && columnEl != null && target != null) {
|
|
95
|
+
const rect = columnEl.getBoundingClientRect();
|
|
96
|
+
const targetRect = target.getBoundingClientRect();
|
|
97
|
+
overlayPosition = {
|
|
98
|
+
x: targetRect.left - rect.left,
|
|
99
|
+
y: targetRect.top - rect.top,
|
|
100
|
+
width: targetRect.width,
|
|
101
|
+
height: targetRect.height,
|
|
102
|
+
};
|
|
164
103
|
}
|
|
165
|
-
}, [selectedUnit, units]);
|
|
166
104
|
|
|
167
|
-
|
|
105
|
+
set(selectedUnitIDAtom, unitID);
|
|
106
|
+
set(overlayPositionAtom, overlayPosition);
|
|
107
|
+
|
|
108
|
+
return unit;
|
|
109
|
+
},
|
|
110
|
+
);
|
|
111
|
+
|
|
112
|
+
export function useAtomOverlayPosition() {
|
|
113
|
+
return scope.useAtomValue(overlayPositionAtom);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export function UnitSelectionCallbackManager({
|
|
117
|
+
onUnitSelected,
|
|
118
|
+
}: UnitSelectionCallbacks) {
|
|
119
|
+
const selectedUnit = scope.useAtomValue(selectedUnitAtom);
|
|
120
|
+
useEffect(() => {
|
|
121
|
+
onUnitSelected?.(selectedUnit?.unit_id ?? null, selectedUnit ?? null);
|
|
122
|
+
}, [selectedUnit?.unit_id]);
|
|
123
|
+
return null;
|
|
168
124
|
}
|
|
169
125
|
|
|
126
|
+
/** TODO: figure out if onClickedColumn is still needed
|
|
127
|
+
/** This is not the natural place to get positions within the column,
|
|
128
|
+
* but it will work for now.
|
|
129
|
+
if (props.onClickedColumn) {
|
|
130
|
+
// Infer height from top and bottom height of unit (because that's passed back with the call)
|
|
131
|
+
//const py = event.y;
|
|
132
|
+
//const [bottom, top] = getUnitHeightRange(unit, axisType);
|
|
133
|
+
//const height = Math.abs(bottom - top);
|
|
134
|
+
|
|
135
|
+
const columnClickData: ColumnClickData = {
|
|
136
|
+
unitID: unit?.unit_id,
|
|
137
|
+
unit,
|
|
138
|
+
target,
|
|
139
|
+
height: el?.getBoundingClientRect().height || 0,
|
|
140
|
+
};
|
|
141
|
+
props.onClickedColumn(columnClickData, event);
|
|
142
|
+
}*/
|
|
143
|
+
|
|
170
144
|
export function useUnitSelectionTarget(
|
|
171
145
|
unit: IUnit,
|
|
172
146
|
): [React.RefObject<HTMLElement>, boolean, (evt: Event) => void] {
|
|
173
147
|
const ref = useRef<HTMLElement>();
|
|
174
148
|
const selectedUnit = useSelectedUnit();
|
|
175
|
-
const
|
|
149
|
+
const selectUnit = useUnitSelectionDispatch();
|
|
176
150
|
const selected = selectedUnit?.unit_id == unit.unit_id;
|
|
177
151
|
|
|
178
152
|
const onClick = useCallback(
|
|
179
153
|
(evt: Event) => {
|
|
180
|
-
|
|
181
|
-
onSelectUnit(unit, ref.current, evt);
|
|
154
|
+
selectUnit?.(unit, ref.current);
|
|
182
155
|
evt.stopPropagation();
|
|
183
156
|
},
|
|
184
|
-
[unit,
|
|
157
|
+
[unit, selectUnit],
|
|
185
158
|
);
|
|
186
159
|
|
|
187
160
|
useEffect(() => {
|
|
188
|
-
if (!selected ||
|
|
161
|
+
if (!selected || selectUnit == null) return;
|
|
189
162
|
// In case we haven't set the position of the unit (if we don't have a target), set the selected unit
|
|
190
|
-
|
|
163
|
+
selectUnit(unit, ref.current);
|
|
191
164
|
|
|
192
165
|
// Scroll the unit into view
|
|
193
166
|
ref.current?.scrollIntoView({
|
|
@@ -195,7 +168,7 @@ export function useUnitSelectionTarget(
|
|
|
195
168
|
block: "center",
|
|
196
169
|
inline: "nearest",
|
|
197
170
|
});
|
|
198
|
-
}, [selected,
|
|
171
|
+
}, [selected, selectUnit]);
|
|
199
172
|
|
|
200
173
|
return [ref, selected, onClick];
|
|
201
174
|
}
|
|
@@ -219,7 +192,7 @@ export function UnitKeyboardNavigation<T extends BaseUnit>({
|
|
|
219
192
|
(event) => {
|
|
220
193
|
const nextIx = keyMap[event.keyCode];
|
|
221
194
|
if (nextIx == null || nextIx < 0 || nextIx >= units.length) return;
|
|
222
|
-
selectUnit(units[nextIx], null
|
|
195
|
+
selectUnit(units[nextIx], null);
|
|
223
196
|
event.stopPropagation();
|
|
224
197
|
},
|
|
225
198
|
[units, ix],
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import hyper from "@macrostrat/hyper";
|
|
2
2
|
import { Popover } from "@blueprintjs/core";
|
|
3
3
|
import styles from "./popover.module.sass";
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
useAtomOverlayPosition,
|
|
6
|
+
useSelectedUnit,
|
|
7
|
+
useUnitSelectionDispatch,
|
|
8
|
+
} from "../data-provider";
|
|
5
9
|
import { UnitDetailsPanel } from "./panel";
|
|
6
10
|
|
|
7
11
|
const h = hyper.styled(styles);
|
|
@@ -54,8 +58,8 @@ function InteractionBarrier({ children }) {
|
|
|
54
58
|
|
|
55
59
|
export function UnitSelectionPopover() {
|
|
56
60
|
const unit = useSelectedUnit();
|
|
57
|
-
const selectUnit =
|
|
58
|
-
const position =
|
|
61
|
+
const selectUnit = useUnitSelectionDispatch();
|
|
62
|
+
const position = useAtomOverlayPosition();
|
|
59
63
|
if (unit == null) {
|
|
60
64
|
return null;
|
|
61
65
|
}
|
|
@@ -79,7 +83,7 @@ export function UnitSelectionPopover() {
|
|
|
79
83
|
className: "legend-panel",
|
|
80
84
|
onSelectUnit: (id: number) => {
|
|
81
85
|
console.log("Selected unit in popover:", id);
|
|
82
|
-
selectUnit(id, null
|
|
86
|
+
selectUnit(id, null);
|
|
83
87
|
},
|
|
84
88
|
}),
|
|
85
89
|
),
|