Skip to content

Commit 1f9e893

Browse files
authored
Merge branch 'main' into lith-tag-update
2 parents cd75c13 + 8d228c9 commit 1f9e893

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+1903
-881
lines changed

README.md

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,25 @@ this by creating a `.env` file in the root of the repository.
4747

4848
### Developing components
4949

50-
#### Using Storybook as a component workbench
50+
#### The Storybook component workbench
5151

5252
We use [Storybook](https://storybook.js.org/) for developing components in an
5353
isolated environment. To start the storybook, run `yarn run dev` in the root
5454
directory. The storybook will start at port `6006`. You can then create new
55-
'stories' referencing components to create standalone views. This is the main
56-
approach for component development preferred by the Macrostrat team.
55+
'stories' referencing components to create standalone views.
56+
57+
When you make a change to a component, it is crucial to make sure that the
58+
examples in the Storybook continue to work. If you have to update existing
59+
stories, it is likely you will need to update API documentation and Changelog to
60+
reflect the breaking change.
61+
62+
#### Changelog
63+
64+
If you make a change to a component, you should update the changelog for the
65+
containing package (the `CHANGELOG.md` file in the package directory).
66+
Unreleased changes can be described in an `Unreleased` section at the top of the
67+
changelog. Upon publishing the package, the full changelog will be compiled from
68+
the `Unreleased` section and any prerelease changes.
5769

5870
#### Developing components in a consuming application
5971

packages/column-components/src/context/layout.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,12 +178,19 @@ function GrainsizeLayoutProvider({
178178
);
179179
}
180180

181-
const useColumnLayout = () => useContext(ColumnLayoutContext);
181+
export function useColumnLayout() {
182+
const ctx = useContext(ColumnLayoutContext);
183+
if (ctx == null) {
184+
throw new Error(
185+
"useColumnLayout must be used within a ColumnLayoutProvider"
186+
);
187+
}
188+
return ctx;
189+
}
182190

183191
export {
184192
ColumnLayoutContext,
185193
ColumnLayoutProvider,
186194
CrossAxisLayoutProvider,
187195
GrainsizeLayoutProvider,
188-
useColumnLayout,
189196
};

packages/column-components/src/main.module.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@
3030
.col-note-label {
3131
padding-left: 0.3em;
3232
border-left: 1px solid var(--note-color);
33+
margin: 1px 0;
3334
font-style: italic;
34-
margin: 0;
3535
z-index: 15;
3636
}
3737
g.height-range line {

packages/column-components/src/notes/connector.ts

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,14 @@ interface NotePositionerProps {
88
offsetY: number;
99
noteHeight: number;
1010
children?: ReactNode;
11+
onClick?: (event: React.MouseEvent) => void;
1112
}
1213

1314
const NotePositioner = forwardRef(function (
1415
props: NotePositionerProps,
1516
ref: any
1617
) {
17-
let { offsetY, noteHeight, children } = props;
18+
let { offsetY, noteHeight, onClick, children } = props;
1819
const { width, paddingLeft } = useContext(NoteLayoutContext);
1920
if (noteHeight == null) {
2021
noteHeight = 0;
@@ -23,12 +24,6 @@ const NotePositioner = forwardRef(function (
2324

2425
let y = offsetY - noteHeight / 2 - outerPad;
2526

26-
// HACK: override y position for Safari
27-
// (foreign objects don't work too well)
28-
if (navigator.userAgent.includes("Safari")) {
29-
y += 5;
30-
}
31-
3227
return h(
3328
ForeignObject,
3429
{
@@ -43,6 +38,7 @@ const NotePositioner = forwardRef(function (
4338
"div.note-inner",
4439
{
4540
ref,
41+
onClick,
4642
style: { margin: outerPad },
4743
},
4844
children
@@ -56,8 +52,18 @@ const findIndex = function (note) {
5652
return notes.indexOf(note);
5753
};
5854

59-
const NoteConnector = function (props) {
60-
let { note, node, index } = props;
55+
export interface NodeConnectorOptions {
56+
deltaConnectorAttachment?: number; // Delta for connector attachment
57+
}
58+
59+
type NodeConnectorProps = NodeConnectorOptions & {
60+
note: any; // Note data type
61+
node?: any; // Node data type
62+
index?: number; // Index of the note in the layout
63+
};
64+
65+
const NoteConnector = function (props: NodeConnectorProps) {
66+
let { note, node, deltaConnectorAttachment, index } = props;
6167
// Try to avoid scanning for index if we can
6268
if (index == null) {
6369
index = findIndex(note);
@@ -68,6 +74,11 @@ const NoteConnector = function (props) {
6874
if (node == null) {
6975
node = nodes[note.id];
7076
}
77+
78+
if (node != null && deltaConnectorAttachment != null) {
79+
node.currentPos += deltaConnectorAttachment;
80+
}
81+
7182
const offsetX = (columnIndex[index] || 0) * 5;
7283

7384
return h([

packages/column-components/src/notes/height-range.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ function HeightRangeAnnotation(props: HeightRangeAnnotationProps) {
1717
top_height,
1818
offsetX = 0,
1919
color,
20-
lineInset = 2.5,
20+
lineInset = 1,
2121
...rest
2222
} = props;
2323

packages/column-components/src/notes/index.ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ import {
1212
NoteEditorProvider,
1313
} from "./editor";
1414
import { NewNotePositioner } from "./new";
15+
import { NodeConnectorOptions } from "./connector";
1516
export * from "./types";
17+
import type { ReactNode } from "react";
1618

1719
interface NoteComponentProps {
1820
visibility: string;
@@ -73,6 +75,7 @@ function EditableNotesColumn(props: EditableNotesColumnProps) {
7375
noteEditor = NoteTextEditor,
7476
allowPositionEditing = false,
7577
forceOptions,
78+
onClickNote,
7679
} = props;
7780

7881
const innerWidth = width - paddingLeft;
@@ -103,6 +106,7 @@ function EditableNotesColumn(props: EditableNotesColumnProps) {
103106
h(NotesList, {
104107
editHandler: inEditMode ? onUpdateNote : null,
105108
inEditMode,
109+
onClickNote,
106110
}),
107111
h(NewNotePositioner),
108112
h(NoteEditor, { allowPositionEditing }),
@@ -113,21 +117,27 @@ function EditableNotesColumn(props: EditableNotesColumnProps) {
113117
);
114118
}
115119

116-
interface NotesColumnBaseProps {
120+
interface NotesColumnBaseProps extends NodeConnectorOptions {
117121
width?: number;
118122
paddingLeft?: number;
119123
transform?: string;
120124
notes?: NoteData[];
121125
noteComponent?: ComponentType<any>;
126+
onClickNote?: (note: NoteData) => void;
127+
children?: ReactNode;
122128
}
123129

124130
function StaticNotesColumn(props: NotesColumnBaseProps) {
131+
/** A non-editable notes column. */
125132
const {
126133
width,
127134
paddingLeft = 60,
128135
transform,
129136
notes,
130137
noteComponent = NoteComponent,
138+
deltaConnectorAttachment,
139+
onClickNote,
140+
children,
131141
} = props;
132142

133143
const innerWidth = width - paddingLeft;
@@ -143,7 +153,12 @@ function StaticNotesColumn(props: NotesColumnBaseProps) {
143153
[
144154
h("g.section-log", { transform }, [
145155
h(NoteDefs),
146-
h(NotesList, { inEditMode: false }),
156+
h(NotesList, {
157+
inEditMode: false,
158+
deltaConnectorAttachment,
159+
onClickNote,
160+
}),
161+
children,
147162
]),
148163
]
149164
);

packages/column-components/src/notes/layout.ts

Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,17 @@ import { StatefulComponent } from "@macrostrat/ui-components";
33
import h from "@macrostrat/hyper";
44

55
import { hasSpan } from "./utils";
6-
import { FlexibleNode, Node, Renderer, Force } from "./label-primitives";
6+
import { FlexibleNode, Force, Node, Renderer } from "./label-primitives";
77
import {
8-
ColumnLayoutProvider,
98
ColumnContext,
109
ColumnCtx,
1110
ColumnDivision,
11+
ColumnLayoutProvider,
1212
} from "../context";
13+
import {
14+
AgeRangeRelationship,
15+
compareAgeRanges,
16+
} from "@macrostrat/stratigraphy-utils";
1317

1418
const NoteLayoutContext = createContext(null);
1519

@@ -42,19 +46,16 @@ const buildColumnIndex = function () {
4246
};
4347
};
4448

45-
const withinDomain = (scale) =>
46-
function (d) {
47-
const [start, end] = scale.domain();
48-
// end height greater than beginning
49-
const end_height = d.top_height || d.height;
50-
if (start < end) {
51-
// Normal scale (e.g. height)
52-
return end_height >= start && d.height <= end;
53-
} else {
54-
// Inverted scale (e.g. time)
55-
return end_height <= start && d.height >= end;
56-
}
49+
function withinDomain(scale) {
50+
const scaleDomain = scale.domain();
51+
return (d) => {
52+
const noteRange: [number, number] = [d.height, d.top_height ?? d.height];
53+
54+
const rel = compareAgeRanges(scaleDomain, noteRange);
55+
56+
return rel !== AgeRangeRelationship.Disjoint;
5757
};
58+
}
5859

5960
interface NoteLayoutProviderProps {
6061
notes: any[];
@@ -70,6 +71,7 @@ interface NoteLayoutState {
7071
elementHeights?: object;
7172
columnIndex?: object;
7273
nodes?: object;
74+
updateHeight?: Function;
7375
generatePath: Function;
7476
createNodeForNote?: Function;
7577
noteComponent?: any;
@@ -81,7 +83,7 @@ export interface NoteLayoutCtx {
8183
paddingLeft: number;
8284
scale: Function;
8385
width: number;
84-
registerHeight: Function;
86+
updateHeight: Function;
8587
generatePath: Function;
8688
columnIndex?: any;
8789
nodes?: any;
@@ -110,7 +112,7 @@ class NoteLayoutProvider extends StatefulComponent<
110112
this.generatePath = this.generatePath.bind(this);
111113
this.createNodeForNote = this.createNodeForNote.bind(this);
112114
this.computeForceLayout = this.computeForceLayout.bind(this);
113-
this.registerHeight = this.registerHeight.bind(this);
115+
this.updateHeight = this.updateHeight.bind(this);
114116
this.updateNotes = this.updateNotes.bind(this);
115117
this.componentDidMount = this.componentDidMount.bind(this);
116118
this.componentDidUpdate = this.componentDidUpdate.bind(this);
@@ -148,8 +150,6 @@ class NoteLayoutProvider extends StatefulComponent<
148150
paddingLeft,
149151
scale,
150152
width,
151-
registerHeight: this.registerHeight,
152-
generatePath: this.generatePath,
153153
};
154154

155155
// Compute force layout
@@ -161,6 +161,8 @@ class NoteLayoutProvider extends StatefulComponent<
161161

162162
return this.setState({
163163
renderer,
164+
updateHeight: this.updateHeight,
165+
generatePath: this.generatePath,
164166
...forwardedValues,
165167
});
166168
}
@@ -195,18 +197,19 @@ class NoteLayoutProvider extends StatefulComponent<
195197
const { id: noteID } = note;
196198
const pixelHeight = elementHeights[noteID] || 10;
197199
const padding = 5;
198-
const lowerHeight = scale(note.height);
200+
let noteHeight = scale(note.height);
199201
if (hasSpan(note)) {
200202
const upperHeight = scale(note.top_height);
201203
const harr: [number, number] = [
202-
lowerHeight - padding,
204+
noteHeight - padding,
203205
upperHeight + padding,
204206
];
205207
if (harr[0] - harr[1] > 0) {
206208
return new FlexibleNode(harr, pixelHeight);
207209
}
210+
noteHeight = (harr[0] + harr[1]) / 2;
208211
}
209-
return new Node(lowerHeight, pixelHeight);
212+
return new Node(noteHeight, pixelHeight);
210213
}
211214

212215
computeForceLayout(prevProps, prevState) {
@@ -250,7 +253,7 @@ class NoteLayoutProvider extends StatefulComponent<
250253
return this.updateState({ nodes: { $set: nodesObj } });
251254
}
252255

253-
registerHeight(id, height) {
256+
updateHeight(id, height) {
254257
if (height == null) {
255258
return;
256259
}
@@ -332,4 +335,12 @@ const NoteUnderlay = function ({ fill, ...rest }) {
332335
});
333336
};
334337

338+
export function useNoteLayout() {
339+
const ctx = useContext(NoteLayoutContext);
340+
if (ctx == null) {
341+
throw new Error("useNoteLayout must be used within a NoteLayoutProvider");
342+
}
343+
return ctx;
344+
}
345+
335346
export { NoteLayoutContext, NoteLayoutProvider, NoteRect, NoteUnderlay };

packages/column-components/src/notes/note.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
padding-left: 0.3em;
3232
border-left: 1px solid var(--note-color);
3333
font-style: italic;
34-
margin: 0;
3534
z-index: 15;
3635
}
3736
g.height-range line {
@@ -65,3 +64,4 @@ g.note-editor .link {
6564
#new_arrow_end {
6665
fill: #1e90ff;
6766
}
67+

0 commit comments

Comments
 (0)