@macrostrat/column-components
Version:
React rendering primitives for stratigraphic columns
310 lines (299 loc) • 12.1 kB
JavaScript
import $f5b828bbb980a05d$export$2e2bcd8739ae039 from "./column-components.de2f942b.js";
import {ColumnLayoutContext as $25Kj1$ColumnLayoutContext} from "./column-components.0ccab336.js";
import {format as $25Kj1$format} from "d3-format";
import {useContext as $25Kj1$useContext, createRef as $25Kj1$createRef, Component as $25Kj1$Component} from "react";
import {Popover as $25Kj1$Popover, Position as $25Kj1$Position, Button as $25Kj1$Button, Intent as $25Kj1$Intent} from "@blueprintjs/core";
import $25Kj1$chromajs from "chroma-js";
import $25Kj1$uibox from "ui-box";
const $c5268cfbf945365e$var$fmt = (0, $25Kj1$format)(".1f");
const $c5268cfbf945365e$var$fmt2 = (0, $25Kj1$format)(".2f");
const $c5268cfbf945365e$var$IntervalNotification = function(props) {
const { id: id, height: height, bottom: bottom, top: top, surface: surface } = props;
return (0, $f5b828bbb980a05d$export$2e2bcd8739ae039)("div", [
(0, $f5b828bbb980a05d$export$2e2bcd8739ae039)("h4", `Section ${id} @ ${$c5268cfbf945365e$var$fmt(height)} m`),
(0, $f5b828bbb980a05d$export$2e2bcd8739ae039)("p", [
"Interval ID: ",
(0, $f5b828bbb980a05d$export$2e2bcd8739ae039)("code", id)
]),
(0, $f5b828bbb980a05d$export$2e2bcd8739ae039)("p", `${bottom} - ${top} m`),
surface ? (0, $f5b828bbb980a05d$export$2e2bcd8739ae039)("p", [
"Surface: ",
(0, $f5b828bbb980a05d$export$2e2bcd8739ae039)("code", surface)
]) : null
]);
};
const $c5268cfbf945365e$var$PopoverEditorTitle = function(props) {
const { interval: interval, children: children } = props;
return (0, $f5b828bbb980a05d$export$2e2bcd8739ae039)("div.interval-editor-title", [
(0, $f5b828bbb980a05d$export$2e2bcd8739ae039)("h3", `${$c5268cfbf945365e$var$fmt2(interval.bottom)}\u{2013}${$c5268cfbf945365e$var$fmt2(interval.top)} m`),
(0, $f5b828bbb980a05d$export$2e2bcd8739ae039)("div.id", [
(0, $f5b828bbb980a05d$export$2e2bcd8739ae039)("code", interval.id)
]),
children
]);
};
const $c5268cfbf945365e$var$OverlayBox = (props)=>{
const { division: division, background: background, className: className, onClick: onClick } = props;
const { widthForDivision: widthForDivision, scaleClamped: scaleClamped } = (0, $25Kj1$useContext)((0, $25Kj1$ColumnLayoutContext));
if (scaleClamped == null) return null;
const top = scaleClamped(division.top);
const bottom = scaleClamped(division.bottom);
const height = bottom - top;
const width = widthForDivision(division);
const style = {
marginTop: top,
height: height,
width: width,
pointerEvents: "none",
position: "absolute"
};
return (0, $f5b828bbb980a05d$export$2e2bcd8739ae039)("div", {
style: style
}, [
(0, $f5b828bbb980a05d$export$2e2bcd8739ae039)("div", {
onClick: onClick,
className: className,
style: {
cursor: onClick != null ? "pointer" : null,
width: "100%",
height: "100%",
background: background
}
}),
props.children
]);
};
const $c5268cfbf945365e$var$EditingBox = function({ division: division, color: color, ...rest }) {
if (division == null) return null;
if (color == null) color = "red";
const background = (0, $25Kj1$chromajs)(color).alpha(0.5).css();
return (0, $f5b828bbb980a05d$export$2e2bcd8739ae039)($c5268cfbf945365e$var$OverlayBox, {
className: "editing-box",
division: division,
background: background,
...rest
});
};
class $c5268cfbf945365e$export$76fcb8530f09ae2e extends (0, $25Kj1$Component) {
static{
this.contextType = (0, $25Kj1$ColumnLayoutContext);
}
static{
this.defaultProps = {
onHoverInterval () {},
onClick () {},
left: 0,
top: 0,
showInfoBox: false,
allowEditing: true,
renderEditorPopup () {
return null;
},
color: "red",
popoverWidth: 340
};
}
constructor(props){
super(props);
this.onHoverInterval = this.onHoverInterval.bind(this);
this.removeHoverBox = this.removeHoverBox.bind(this);
this.heightForEvent = this.heightForEvent.bind(this);
this.onEditInterval = this.onEditInterval.bind(this);
this.onClick = this.onClick.bind(this);
this.renderCursorLine = this.renderCursorLine.bind(this);
this.renderHoveredBox = this.renderHoveredBox.bind(this);
this.closePopover = this.closePopover.bind(this);
this.state = {
height: null,
hoveredDivision: null,
popoverIsOpen: false
};
this.timeout = null;
this.elementRef = (0, $25Kj1$createRef)();
}
onHoverInterval(event) {
event.stopPropagation();
// findDOMNode might be slow but I'm not sure
if (this.elementRef.current !== event.target) return;
const height = this.heightForEvent(event);
this.setState({
height: height
});
if (!this.props.allowEditing) return;
const { divisions: divisions } = this.context;
let division = null;
for (let d of Array.from(divisions))if (d.bottom <= height && height < d.top) {
division = d;
break;
}
if (division === this.state.hoveredDivision) return;
this.setState({
hoveredDivision: division
});
if (this.timeout != null) {
clearTimeout(this.timeout);
return this.timeout = null;
}
}
removeHoverBox() {
this.setState({
hoveredDivision: null,
popoverIsOpen: false
});
return this.timeout = null;
}
heightForEvent(event) {
const { scale: scale } = this.context;
const { offsetY: offsetY } = event.nativeEvent;
return scale.invert(offsetY);
}
onEditInterval(event) {
if (this.state.popoverIsOpen) return;
// This could be moved to the actual interval
// wrapped with a withRouter
const { showInfoBox: showInfoBox } = this.props;
const { hoveredDivision: hoveredDivision } = this.state;
const height = this.heightForEvent(event);
event.stopPropagation();
if (event.shiftKey && showInfoBox) {
this.setState({
popoverIsOpen: true
});
return;
}
return this.props.onClick({
event: event,
height: height,
division: hoveredDivision
});
}
onClick(event) {
// This event handler might be unnecessary
if (this.props.allowEditing) return this.onEditInterval(event);
const height = this.heightForEvent(event);
return this.props.onClick({
height: height
});
}
renderCursorLine() {
let { height: height, hoveredDivision: hoveredDivision } = this.state;
const { scaleClamped: scaleClamped } = this.context;
// Show the height we have selected if we are not hovering
const { selectedHeight: selectedHeight } = this.props;
if (height == null) height = selectedHeight;
if (height == null) return;
const style = {
top: scaleClamped(height),
height: 0,
border: "0.5px solid black",
width: this.context.widthForDivision(hoveredDivision),
position: "absolute",
pointerEvents: "none"
};
return (0, $f5b828bbb980a05d$export$2e2bcd8739ae039)("div.cursor", {
style: style
}, [
(0, $f5b828bbb980a05d$export$2e2bcd8739ae039)("div.cursor-position", {
style: {
pointerEvents: "none",
fontWeight: "bold",
fontSize: "12px",
left: "2px",
top: "-14px",
position: "absolute",
color: "black"
}
}, [
$c5268cfbf945365e$var$fmt2(height)
])
]);
}
renderHoveredBox() {
if (this.state.hoveredDivision == null) return null;
const { popoverIsOpen: popoverIsOpen, hoveredDivision: division } = this.state;
const width = this.context.widthForDivision(division);
const { color: color } = this.props;
const background = (0, $25Kj1$chromajs)(color).alpha(0.3).css();
return (0, $f5b828bbb980a05d$export$2e2bcd8739ae039)($c5268cfbf945365e$var$OverlayBox, {
division: division,
className: "hovered-box",
background: background
}, [
(0, $f5b828bbb980a05d$export$2e2bcd8739ae039).if(this.props.renderEditorPopup != null)((0, $25Kj1$Popover), {
isOpen: popoverIsOpen && division != null,
//style: { display: "block", width },
position: (0, $25Kj1$Position).LEFT
}, [
(0, $f5b828bbb980a05d$export$2e2bcd8739ae039)("div", {
style: {
width: width,
height: 30,
transform: "translate(0,-30)"
}
}),
(0, $f5b828bbb980a05d$export$2e2bcd8739ae039)("div.editor-popover-contents", {
style: {
width: this.props.popoverWidth,
padding: "10px"
}
}, [
(0, $f5b828bbb980a05d$export$2e2bcd8739ae039)($c5268cfbf945365e$var$PopoverEditorTitle, {
interval: division
}, [
(0, $f5b828bbb980a05d$export$2e2bcd8739ae039)((0, $25Kj1$Button), {
icon: "cross",
minimal: true,
intent: (0, $25Kj1$Intent).WARNING,
onClick: this.closePopover.bind(this)
})
]),
this.props.renderEditorPopup(division)
])
])
]);
}
closePopover() {
return this.setState({
popoverIsOpen: false
});
}
render() {
let { divisions: divisions, pixelHeight: pixelHeight, width: width } = this.context;
const { popoverIsOpen: popoverIsOpen, hoveredDivision: division } = this.state;
const { left: left, top: top, color: color } = this.props;
if (width == null) ({ width: width } = this.props);
return (0, $f5b828bbb980a05d$export$2e2bcd8739ae039)((0, $25Kj1$uibox), {
className: "edit-overlay",
width: width,
height: pixelHeight,
ref: this.elementRef,
style: {
left: left,
top: top,
position: "absolute",
zIndex: 18,
pointerEvents: "all",
cursor: "pointer"
},
onClick: this.onEditInterval,
onMouseEnter: this.onHoverInterval,
onMouseMove: this.onHoverInterval,
onMouseLeave: ()=>{
if (popoverIsOpen) return;
this.setState({
height: null
});
return this.timeout = setTimeout(this.removeHoverBox, 1000);
}
}, [
this.renderHoveredBox(),
(0, $f5b828bbb980a05d$export$2e2bcd8739ae039)($c5268cfbf945365e$var$EditingBox, {
division: this.props.editingInterval,
color: color
}),
this.renderCursorLine()
]);
}
}
export {$c5268cfbf945365e$export$76fcb8530f09ae2e as DivisionEditOverlay};
//# sourceMappingURL=column-components.4e11ccaf.js.map