UNPKG

@macrostrat/column-components

Version:

React rendering primitives for stratigraphic columns

310 lines (299 loc) 12.1 kB
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