@macrostrat/feedback-components 1.0.1 → 1.1.1
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 +10 -0
- package/dist/esm/feedback-components.3b3a5357.js +137 -0
- package/dist/esm/feedback-components.3b3a5357.js.map +1 -0
- package/dist/esm/feedback-components.46a7a347.js +269 -0
- package/dist/esm/feedback-components.46a7a347.js.map +1 -0
- package/dist/esm/{node.28634e40.js → feedback-components.5509fab3.js} +11 -6
- package/dist/esm/feedback-components.5509fab3.js.map +1 -0
- package/dist/esm/feedback-components.586103e8.js +578 -0
- package/dist/esm/feedback-components.586103e8.js.map +1 -0
- package/dist/esm/{extractions.65bb73cc.js → feedback-components.5df2a926.js} +46 -18
- package/dist/esm/feedback-components.5df2a926.js.map +1 -0
- package/dist/esm/{main.module.cd706d67.js → feedback-components.6d32ee91.js} +1 -1
- package/dist/esm/{main.module.cd706d67.js.map → feedback-components.6d32ee91.js.map} +1 -1
- package/dist/esm/feedback-components.95dbe7d7.js +82 -0
- package/dist/esm/feedback-components.95dbe7d7.js.map +1 -0
- package/dist/esm/{type-selector.6e8952d6.js → feedback-components.ad9f284e.js} +6 -5
- package/dist/esm/feedback-components.ad9f284e.js.map +1 -0
- package/dist/esm/{main.module.8d366b6e.css → feedback-components.bf93773c.css} +1 -1
- package/dist/esm/{main.module.8d366b6e.css.map → feedback-components.bf93773c.css.map} +1 -1
- package/dist/esm/{main.module.2f2972c8.css → feedback-components.e273ed5b.css} +1 -1
- package/dist/esm/{main.module.2f2972c8.css.map → feedback-components.e273ed5b.css.map} +1 -1
- package/dist/esm/{main.module.d2fbdf09.js → feedback-components.f9850d85.js} +1 -1
- package/dist/esm/{main.module.d2fbdf09.js.map → feedback-components.f9850d85.js.map} +1 -1
- package/dist/esm/{edit-state.c39d8466.js → feedback-components.fa1d3641.js} +125 -7
- package/dist/esm/feedback-components.fa1d3641.js.map +1 -0
- package/dist/esm/feedback-components.fb60c70d.css +180 -0
- package/dist/esm/feedback-components.fb60c70d.css.map +1 -0
- package/dist/esm/index.d.ts +10 -64
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +2 -2
- package/dist/node/feedback-components.2f391fa4.js +2 -0
- package/dist/node/feedback-components.2f391fa4.js.map +1 -0
- package/dist/node/feedback-components.561466ac.js +2 -0
- package/dist/node/feedback-components.561466ac.js.map +1 -0
- package/dist/node/feedback-components.571ee23c.js +2 -0
- package/dist/node/feedback-components.571ee23c.js.map +1 -0
- package/dist/node/{main.module.ebdf985b.js → feedback-components.794f429b.js} +2 -2
- package/dist/node/feedback-components.794f429b.js.map +1 -0
- package/dist/node/{main.module.1fdfe813.css → feedback-components.83c21466.css} +1 -1
- package/dist/node/feedback-components.83c21466.css.map +1 -0
- package/dist/node/feedback-components.8b03e8be.js +2 -0
- package/dist/node/feedback-components.8b03e8be.js.map +1 -0
- package/dist/node/{main.module.6bc7d51b.css → feedback-components.9eb1d41a.css} +1 -1
- package/dist/node/feedback-components.9eb1d41a.css.map +1 -0
- package/dist/node/feedback-components.a39f7653.js +2 -0
- package/dist/node/feedback-components.a39f7653.js.map +1 -0
- package/dist/node/feedback-components.acac789b.js +2 -0
- package/dist/node/feedback-components.acac789b.js.map +1 -0
- package/dist/node/feedback-components.b7946db4.js +2 -0
- package/dist/node/feedback-components.b7946db4.js.map +1 -0
- package/dist/node/feedback-components.c459cc27.js +2 -0
- package/dist/node/feedback-components.c459cc27.js.map +1 -0
- package/dist/node/feedback-components.c88cb37f.css +2 -0
- package/dist/node/feedback-components.c88cb37f.css.map +1 -0
- package/dist/node/feedback-components.ec54a1e7.js +2 -0
- package/dist/node/feedback-components.ec54a1e7.js.map +1 -0
- package/dist/node/index.js +1 -1
- package/dist/node/index.js.map +1 -1
- package/package.json +7 -6
- package/src/extractions/index.ts +76 -21
- package/src/extractions/types.ts +6 -1
- package/src/feedback/edit-state.ts +184 -16
- package/src/feedback/feedback.module.sass +121 -9
- package/src/feedback/graph.ts +90 -32
- package/src/feedback/index.ts +553 -146
- package/src/feedback/node.ts +7 -1
- package/src/feedback/text-visualizer.ts +286 -49
- package/src/feedback/type-selector/index.ts +4 -2
- package/dist/esm/edit-state.c39d8466.js.map +0 -1
- package/dist/esm/extractions.65bb73cc.js.map +0 -1
- package/dist/esm/feedback.5c86878e.js +0 -252
- package/dist/esm/feedback.5c86878e.js.map +0 -1
- package/dist/esm/feedback.module.55921afe.css +0 -44
- package/dist/esm/feedback.module.55921afe.css.map +0 -1
- package/dist/esm/feedback.module.765b1e58.js +0 -28
- package/dist/esm/feedback.module.765b1e58.js.map +0 -1
- package/dist/esm/graph.f4f65d79.js +0 -83
- package/dist/esm/graph.f4f65d79.js.map +0 -1
- package/dist/esm/node.28634e40.js.map +0 -1
- package/dist/esm/text-visualizer.198e27ff.js +0 -101
- package/dist/esm/text-visualizer.198e27ff.js.map +0 -1
- package/dist/esm/type-selector.6e8952d6.js.map +0 -1
- package/dist/node/edit-state.f50ca728.js +0 -2
- package/dist/node/edit-state.f50ca728.js.map +0 -1
- package/dist/node/extractions.e6ea2eb9.js +0 -2
- package/dist/node/extractions.e6ea2eb9.js.map +0 -1
- package/dist/node/feedback.8d3d1219.js +0 -2
- package/dist/node/feedback.8d3d1219.js.map +0 -1
- package/dist/node/feedback.module.a8744203.js +0 -2
- package/dist/node/feedback.module.a8744203.js.map +0 -1
- package/dist/node/feedback.module.c4eab97d.css +0 -2
- package/dist/node/feedback.module.c4eab97d.css.map +0 -1
- package/dist/node/graph.ca5b649f.js +0 -2
- package/dist/node/graph.ca5b649f.js.map +0 -1
- package/dist/node/main.module.1857be22.js +0 -2
- package/dist/node/main.module.1857be22.js.map +0 -1
- package/dist/node/main.module.1fdfe813.css.map +0 -1
- package/dist/node/main.module.6bc7d51b.css.map +0 -1
- package/dist/node/main.module.ebdf985b.js.map +0 -1
- package/dist/node/node.33108ccc.js +0 -2
- package/dist/node/node.33108ccc.js.map +0 -1
- package/dist/node/text-visualizer.1e770afa.js +0 -2
- package/dist/node/text-visualizer.1e770afa.js.map +0 -1
- package/dist/node/type-selector.0035ef7d.js +0 -2
- package/dist/node/type-selector.0035ef7d.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,16 @@ All notable changes to this project will be documented in this file. The format
|
|
|
4
4
|
is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this
|
|
5
5
|
project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
+
## [1.1.1] - 2025-07-01
|
|
8
|
+
|
|
9
|
+
- new text component, following same clicking rules as tree
|
|
10
|
+
- Entity panel updates
|
|
11
|
+
- Entity types are editable, deletable, and addable
|
|
12
|
+
|
|
13
|
+
## [1.1.0] - 2025-06-25
|
|
14
|
+
|
|
15
|
+
Major updates by David Sklar to improve usability
|
|
16
|
+
|
|
7
17
|
## [1.0.1] - 2025-02-15
|
|
8
18
|
|
|
9
19
|
Added a `node` target to bundle without imported CSS.
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import {treeToGraph as $b79bf29960412ca7$export$8d9dbb7a64bf2a5e} from "./feedback-components.fa1d3641.js";
|
|
2
|
+
import "./feedback-components.fb60c70d.css";
|
|
3
|
+
import $phGch$feedbackcomponents95dbe7d7js from "./feedback-components.95dbe7d7.js";
|
|
4
|
+
import {getTagStyle as $03d8811e9c9b360d$export$35baa338324d8550} from "./feedback-components.5df2a926.js";
|
|
5
|
+
import $phGch$macrostrathyper from "@macrostrat/hyper";
|
|
6
|
+
import {forceSimulation as $phGch$forceSimulation, forceLink as $phGch$forceLink, forceManyBody as $phGch$forceManyBody, forceCenter as $phGch$forceCenter, forceCollide as $phGch$forceCollide} from "d3-force";
|
|
7
|
+
import {useState as $phGch$useState, useEffect as $phGch$useEffect} from "react";
|
|
8
|
+
import {Spinner as $phGch$Spinner, Switch as $phGch$Switch} from "@blueprintjs/core";
|
|
9
|
+
import {ErrorBoundary as $phGch$ErrorBoundary} from "@macrostrat/ui-components";
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
function $parcel$interopDefault(a) {
|
|
13
|
+
return a && a.__esModule ? a.default : a;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
const $ff8c3e7f2bc22925$var$h = (0, $phGch$macrostrathyper).styled((0, ($parcel$interopDefault($phGch$feedbackcomponents95dbe7d7js))));
|
|
24
|
+
function $ff8c3e7f2bc22925$export$6a7fe3ef90e8d566(props) {
|
|
25
|
+
// A graph view with react-flow
|
|
26
|
+
// Get positions of nodes using force simulation
|
|
27
|
+
const { tree: tree, width: width, height: height, dispatch: dispatch, selectedNodes: selectedNodes } = props;
|
|
28
|
+
const [nodes, setNodes] = (0, $phGch$useState)(null);
|
|
29
|
+
const [links, setLinks] = (0, $phGch$useState)(null);
|
|
30
|
+
const [showLabels, setShowLabels] = (0, $phGch$useState)(false);
|
|
31
|
+
(0, $phGch$useEffect)(()=>{
|
|
32
|
+
const { nodes: nodes, edges: edges } = (0, $b79bf29960412ca7$export$8d9dbb7a64bf2a5e)(tree);
|
|
33
|
+
const nodesMap = new Map(nodes.map((d)=>[
|
|
34
|
+
d.id,
|
|
35
|
+
d
|
|
36
|
+
]));
|
|
37
|
+
const links = edges.map((d)=>{
|
|
38
|
+
return {
|
|
39
|
+
source: nodesMap.get(d.source),
|
|
40
|
+
target: nodesMap.get(d.dest),
|
|
41
|
+
strength: 1
|
|
42
|
+
};
|
|
43
|
+
});
|
|
44
|
+
const simulation = (0, $phGch$forceSimulation)(nodes).force("link", (0, $phGch$forceLink)(links)).force("charge", (0, $phGch$forceManyBody)().strength(-50)).force("center", (0, $phGch$forceCenter)(width / 2, height / 2)).force("collide", (0, $phGch$forceCollide)().radius(20)).on("tick", ()=>{
|
|
45
|
+
// Update the positions of the nodes
|
|
46
|
+
// setNodes(nodes);
|
|
47
|
+
console.log("Simulation tick");
|
|
48
|
+
}).on("end", ()=>{
|
|
49
|
+
// Update the positions of the nodes
|
|
50
|
+
setNodes(nodes);
|
|
51
|
+
setLinks(links);
|
|
52
|
+
});
|
|
53
|
+
return ()=>{
|
|
54
|
+
simulation.stop();
|
|
55
|
+
};
|
|
56
|
+
}, [
|
|
57
|
+
tree,
|
|
58
|
+
width,
|
|
59
|
+
height
|
|
60
|
+
]);
|
|
61
|
+
if (nodes == null || links == null) return $ff8c3e7f2bc22925$var$h((0, $phGch$Spinner));
|
|
62
|
+
console.log("Graph", nodes, links, selectedNodes);
|
|
63
|
+
return $ff8c3e7f2bc22925$var$h((0, $phGch$ErrorBoundary), {
|
|
64
|
+
description: "An error occurred while rendering the graph view."
|
|
65
|
+
}, $ff8c3e7f2bc22925$var$h("div.graph-view", {
|
|
66
|
+
style: {
|
|
67
|
+
width: width,
|
|
68
|
+
height: height
|
|
69
|
+
}
|
|
70
|
+
}, [
|
|
71
|
+
$ff8c3e7f2bc22925$var$h((0, $phGch$Switch), {
|
|
72
|
+
className: "show-labels-switch",
|
|
73
|
+
label: "Show Labels",
|
|
74
|
+
checked: showLabels,
|
|
75
|
+
onChange: (e)=>setShowLabels(e.target.checked)
|
|
76
|
+
}),
|
|
77
|
+
$ff8c3e7f2bc22925$var$h("svg", {
|
|
78
|
+
width: width,
|
|
79
|
+
height: height
|
|
80
|
+
}, [
|
|
81
|
+
$ff8c3e7f2bc22925$var$h("g.links", links.map((d)=>{
|
|
82
|
+
return $ff8c3e7f2bc22925$var$h("line", {
|
|
83
|
+
x1: d.source.x,
|
|
84
|
+
y1: d.source.y,
|
|
85
|
+
x2: d.target.x,
|
|
86
|
+
y2: d.target.y,
|
|
87
|
+
stroke: "black"
|
|
88
|
+
});
|
|
89
|
+
})),
|
|
90
|
+
$ff8c3e7f2bc22925$var$h("g.nodes", nodes.map((d)=>{
|
|
91
|
+
const active = selectedNodes.includes(d.id);
|
|
92
|
+
const stroke = active ? "white" : "black";
|
|
93
|
+
const highlighted = $ff8c3e7f2bc22925$var$isHighlighted(d.id, selectedNodes, nodes);
|
|
94
|
+
const style = (0, $03d8811e9c9b360d$export$35baa338324d8550)(d.color, {
|
|
95
|
+
highlighted: highlighted,
|
|
96
|
+
active: active
|
|
97
|
+
});
|
|
98
|
+
return $ff8c3e7f2bc22925$var$h("g", [
|
|
99
|
+
$ff8c3e7f2bc22925$var$h("circle", {
|
|
100
|
+
cx: d.x,
|
|
101
|
+
cy: d.y,
|
|
102
|
+
r: 8,
|
|
103
|
+
fill: style.backgroundColor || "blue",
|
|
104
|
+
onClick: (e)=>{
|
|
105
|
+
e.stopPropagation();
|
|
106
|
+
dispatch({
|
|
107
|
+
type: "toggle-node-selected",
|
|
108
|
+
payload: {
|
|
109
|
+
ids: [
|
|
110
|
+
d.id
|
|
111
|
+
]
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
},
|
|
115
|
+
className: active ? "selected" : "",
|
|
116
|
+
stroke: stroke,
|
|
117
|
+
strokeWidth: 2
|
|
118
|
+
}),
|
|
119
|
+
$ff8c3e7f2bc22925$var$h.if(showLabels)("text", {
|
|
120
|
+
x: d.x + 10,
|
|
121
|
+
y: d.y + 4,
|
|
122
|
+
className: "node-label"
|
|
123
|
+
}, d.name || `Node ${d.id}`),
|
|
124
|
+
$ff8c3e7f2bc22925$var$h.if(!showLabels)("title", d.name || `Node ${d.id}`)
|
|
125
|
+
]);
|
|
126
|
+
}))
|
|
127
|
+
])
|
|
128
|
+
]));
|
|
129
|
+
}
|
|
130
|
+
function $ff8c3e7f2bc22925$var$isHighlighted(id, selectedNodes, nodes) {
|
|
131
|
+
if (selectedNodes.length === 0) return true;
|
|
132
|
+
return selectedNodes.includes(id) || nodes.some((node)=>selectedNodes.includes(node.id) && node.children.some((child)=>child.id === id));
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
export {$ff8c3e7f2bc22925$export$6a7fe3ef90e8d566 as GraphView};
|
|
137
|
+
//# sourceMappingURL=feedback-components.3b3a5357.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"mappings":"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","sources":["packages/feedback-components/src/feedback/graph.ts"],"sourcesContent":["import { TreeData } from \"./types\";\nimport { treeToGraph } from \"./edit-state\";\nimport styles from \"./feedback.module.sass\";\nimport hyper from \"@macrostrat/hyper\";\nimport {\n forceSimulation,\n SimulationNodeDatum,\n SimulationLinkDatum,\n forceCenter,\n forceLink,\n forceManyBody,\n forceCollide,\n} from \"d3-force\";\nimport { useEffect, useState } from \"react\";\nimport { Spinner, Switch } from \"@blueprintjs/core\";\nimport { ErrorBoundary } from \"@macrostrat/ui-components\";\nimport { getTagStyle } from \"../extractions\";\n\nconst h = hyper.styled(styles);\n\nexport function GraphView(props: {\n tree: TreeData[];\n width: number;\n height: number;\n dispatch: (action: any) => void;\n selectedNodes: number[];\n}) {\n // A graph view with react-flow\n // Get positions of nodes using force simulation\n const { tree, width, height, dispatch, selectedNodes } = props;\n\n const [nodes, setNodes] = useState<SimulationNodeDatum[]>(null);\n const [links, setLinks] = useState<SimulationLinkDatum[]>(null);\n const [showLabels, setShowLabels] = useState(false);\n\n useEffect(() => {\n const { nodes, edges } = treeToGraph(tree);\n\n const nodesMap = new Map<number, SimulationNodeDatum>(\n nodes.map((d) => [d.id, d]),\n );\n\n const links = edges.map((d) => {\n return {\n source: nodesMap.get(d.source),\n target: nodesMap.get(d.dest),\n strength: 1,\n };\n });\n\n const simulation = forceSimulation(nodes)\n .force(\"link\", forceLink(links))\n .force(\"charge\", forceManyBody().strength(-50))\n .force(\"center\", forceCenter(width / 2, height / 2))\n .force(\"collide\", forceCollide().radius(20))\n .on(\"tick\", () => {\n // Update the positions of the nodes\n // setNodes(nodes);\n console.log(\"Simulation tick\");\n })\n .on(\"end\", () => {\n // Update the positions of the nodes\n setNodes(nodes);\n setLinks(links);\n });\n\n return () => {\n simulation.stop();\n };\n }, [tree, width, height]);\n\n if (nodes == null || links == null) {\n return h(Spinner);\n }\n\n console.log(\"Graph\", nodes, links, selectedNodes);\n\n return h(\n ErrorBoundary,\n {\n description: \"An error occurred while rendering the graph view.\",\n },\n h(\"div.graph-view\", { style: { width, height } }, [\n h(Switch, {\n className: \"show-labels-switch\",\n label: \"Show Labels\",\n checked: showLabels,\n onChange: (e) => setShowLabels(e.target.checked),\n }),\n h(\"svg\", { width, height }, [\n h(\n \"g.links\",\n links.map((d) => {\n return h(\"line\", {\n x1: d.source.x,\n y1: d.source.y,\n x2: d.target.x,\n y2: d.target.y,\n stroke: \"black\",\n });\n }),\n ),\n h(\n \"g.nodes\",\n nodes.map((d) => {\n const active = selectedNodes.includes(d.id);\n const stroke = active ? \"white\" : \"black\";\n const highlighted = isHighlighted(d.id, selectedNodes, nodes);\n const style = getTagStyle(d.color, { highlighted, active });\n\n return h(\"g\", [\n h(\"circle\", {\n cx: d.x,\n cy: d.y,\n r: 8,\n fill: style.backgroundColor || \"blue\",\n onClick: (e) => {\n e.stopPropagation();\n dispatch({\n type: \"toggle-node-selected\",\n payload: { ids: [d.id] },\n });\n },\n className: active ? \"selected\" : \"\",\n stroke,\n strokeWidth: 2,\n }),\n h.if(showLabels)(\n \"text\",\n {\n x: d.x + 10,\n y: d.y + 4,\n className: \"node-label\",\n },\n d.name || `Node ${d.id}`,\n ),\n h.if(!showLabels)(\"title\", d.name || `Node ${d.id}`),\n ]);\n }),\n ),\n ]),\n ]),\n );\n}\n\nfunction isHighlighted(id: number, selectedNodes: number[], nodes: TreeData[]) {\n if (selectedNodes.length === 0) return true;\n return (\n selectedNodes.includes(id) ||\n nodes.some(\n (node) =>\n selectedNodes.includes(node.id) &&\n node.children.some((child) => child.id === id),\n )\n );\n}\n"],"names":[],"version":3,"file":"feedback-components.3b3a5357.js.map"}
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
import "./feedback-components.fb60c70d.css";
|
|
2
|
+
import $aogpP$feedbackcomponents95dbe7d7js from "./feedback-components.95dbe7d7.js";
|
|
3
|
+
import {buildHighlights as $03d8811e9c9b360d$export$c4b91360064ad200, getTagStyle as $03d8811e9c9b360d$export$35baa338324d8550} from "./feedback-components.5df2a926.js";
|
|
4
|
+
import $aogpP$macrostrathyper from "@macrostrat/hyper";
|
|
5
|
+
import {useRef as $aogpP$useRef, useEffect as $aogpP$useEffect} from "react";
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
function $parcel$interopDefault(a) {
|
|
9
|
+
return a && a.__esModule ? a.default : a;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
const $156a3efbc315814c$var$h = (0, $aogpP$macrostrathyper).styled((0, ($parcel$interopDefault($aogpP$feedbackcomponents95dbe7d7js))));
|
|
16
|
+
function $156a3efbc315814c$var$buildTags(highlights, selectedNodes) {
|
|
17
|
+
let tags = [];
|
|
18
|
+
// If entity ID has already been seen, don't add it again
|
|
19
|
+
const entities = new Set();
|
|
20
|
+
for (const highlight of highlights){
|
|
21
|
+
// Don't add multiply-linked entities multiple times
|
|
22
|
+
if (entities.has(highlight.id)) continue;
|
|
23
|
+
const highlighted = $156a3efbc315814c$var$isHighlighted(highlight, selectedNodes);
|
|
24
|
+
const active = $156a3efbc315814c$var$isActive(highlight, selectedNodes);
|
|
25
|
+
const tagStyle = (0, $03d8811e9c9b360d$export$35baa338324d8550)(highlight.backgroundColor, {
|
|
26
|
+
highlighted: highlighted,
|
|
27
|
+
active: active
|
|
28
|
+
});
|
|
29
|
+
const tag = {
|
|
30
|
+
color: tagStyle.color,
|
|
31
|
+
tagStyle: {
|
|
32
|
+
display: "none"
|
|
33
|
+
},
|
|
34
|
+
markStyle: {
|
|
35
|
+
backgroundColor: tagStyle.backgroundColor
|
|
36
|
+
},
|
|
37
|
+
...highlight,
|
|
38
|
+
backgroundColor: tagStyle.backgroundColor
|
|
39
|
+
};
|
|
40
|
+
tags.push(tag);
|
|
41
|
+
entities.add(highlight.id);
|
|
42
|
+
}
|
|
43
|
+
return tags;
|
|
44
|
+
}
|
|
45
|
+
function $156a3efbc315814c$var$isActive(tag, selectedNodes) {
|
|
46
|
+
return selectedNodes.includes(tag.id);
|
|
47
|
+
}
|
|
48
|
+
function $156a3efbc315814c$var$isHighlighted(tag, selectedNodes) {
|
|
49
|
+
if (selectedNodes.length === 0) return true;
|
|
50
|
+
return (selectedNodes.includes(tag.id) || tag.parents?.some((d)=>selectedNodes.includes(d))) ?? false;
|
|
51
|
+
}
|
|
52
|
+
function $156a3efbc315814c$export$6e107db9091b8219(props) {
|
|
53
|
+
// Convert input to tags
|
|
54
|
+
const { text: text, selectedNodes: selectedNodes, nodes: nodes, dispatch: dispatch, allowOverlap: allowOverlap } = props;
|
|
55
|
+
const allTags = $156a3efbc315814c$var$buildTags((0, $03d8811e9c9b360d$export$c4b91360064ad200)(nodes, null), selectedNodes);
|
|
56
|
+
return $156a3efbc315814c$var$h("div.feedback-text-wrapper", {
|
|
57
|
+
tabIndex: 0,
|
|
58
|
+
onKeyDown: (e)=>{
|
|
59
|
+
if (e.key === "Backspace") dispatch({
|
|
60
|
+
type: "delete-node",
|
|
61
|
+
payload: {
|
|
62
|
+
ids: selectedNodes
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
}, $156a3efbc315814c$var$h($156a3efbc315814c$export$190465bec6b893be, {
|
|
67
|
+
text: text,
|
|
68
|
+
allTags: allTags,
|
|
69
|
+
allowOverlap: allowOverlap,
|
|
70
|
+
dispatch: dispatch,
|
|
71
|
+
selectedNodes: selectedNodes
|
|
72
|
+
}));
|
|
73
|
+
}
|
|
74
|
+
function $156a3efbc315814c$var$createTagFromSelection({ container: container }) {
|
|
75
|
+
const selection = window.getSelection();
|
|
76
|
+
if (!selection || selection.isCollapsed || selection.rangeCount === 0 || !container) return null;
|
|
77
|
+
const range = selection.getRangeAt(0);
|
|
78
|
+
if (!container.contains(range.startContainer) || !container.contains(range.endContainer)) return null;
|
|
79
|
+
const preRange = document.createRange();
|
|
80
|
+
preRange.setStart(container, 0);
|
|
81
|
+
preRange.setEnd(range.startContainer, range.startOffset);
|
|
82
|
+
const start = preRange.toString().length;
|
|
83
|
+
const selectedText = range.toString();
|
|
84
|
+
const end = start + selectedText.length;
|
|
85
|
+
return {
|
|
86
|
+
start: start,
|
|
87
|
+
end: end,
|
|
88
|
+
text: selectedText
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
function $156a3efbc315814c$var$addTag({ tag: tag, dispatch: dispatch, text: text, allTags: allTags, allowOverlap: allowOverlap }) {
|
|
92
|
+
let { start: start, end: end } = tag;
|
|
93
|
+
// snap to text
|
|
94
|
+
if (text[end - 1] != " ") {
|
|
95
|
+
// double clicking word overselects by one, shouldn't increase to next word
|
|
96
|
+
while(start > 0 && /\w/.test(text[start - 1]))start--;
|
|
97
|
+
while(end < text.length && /\w/.test(text[end]))end++;
|
|
98
|
+
}
|
|
99
|
+
let payload = {
|
|
100
|
+
start: start,
|
|
101
|
+
end: end,
|
|
102
|
+
text: text.slice(start, end)
|
|
103
|
+
};
|
|
104
|
+
if (payload.text.trim() === "") {
|
|
105
|
+
console.log("Blank tag found, ignoring");
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
const duplicate = allTags.find((t)=>t.start === payload.start && (t.end === payload.end || t.end === payload.end - 1));
|
|
109
|
+
if (duplicate) {
|
|
110
|
+
console.log("Duplicate tag found, ignoring");
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
if (payload.text.endsWith(" ")) {
|
|
114
|
+
payload.text = payload.text.slice(0, -1);
|
|
115
|
+
payload.end -= 1;
|
|
116
|
+
}
|
|
117
|
+
const inside = allTags.some((t)=>t.start <= payload.start && t.end >= payload.end);
|
|
118
|
+
const overlap = allTags.some((t)=>t.start < payload.end && t.end > payload.start);
|
|
119
|
+
if ((inside || overlap) && !allowOverlap) {
|
|
120
|
+
console.log("Tag is inside another tag, ignoring");
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
dispatch({
|
|
124
|
+
type: "create-node",
|
|
125
|
+
payload: payload
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
function $156a3efbc315814c$var$nestHighlights(text, tags) {
|
|
129
|
+
const events = [];
|
|
130
|
+
for (const tag of tags){
|
|
131
|
+
events.push({
|
|
132
|
+
pos: tag.start,
|
|
133
|
+
type: "start",
|
|
134
|
+
tag: tag
|
|
135
|
+
});
|
|
136
|
+
events.push({
|
|
137
|
+
pos: tag.end,
|
|
138
|
+
type: "end",
|
|
139
|
+
tag: tag
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
events.sort((a, b)=>{
|
|
143
|
+
if (a.pos !== b.pos) return a.pos - b.pos;
|
|
144
|
+
if (a.type === "end" && b.type === "start") return -1;
|
|
145
|
+
if (a.type === "start" && b.type === "end") return 1;
|
|
146
|
+
return 0;
|
|
147
|
+
});
|
|
148
|
+
const root = {
|
|
149
|
+
children: [],
|
|
150
|
+
textStart: 0
|
|
151
|
+
};
|
|
152
|
+
const stack = [
|
|
153
|
+
root
|
|
154
|
+
];
|
|
155
|
+
let lastPos = 0;
|
|
156
|
+
for (const { pos: pos, type: type, tag: tag } of events){
|
|
157
|
+
const parent = stack[stack.length - 1];
|
|
158
|
+
if (pos > lastPos) {
|
|
159
|
+
const slice = text.slice(lastPos, pos);
|
|
160
|
+
parent.children.push(slice);
|
|
161
|
+
}
|
|
162
|
+
if (type === "start") {
|
|
163
|
+
const newNode = {
|
|
164
|
+
tag: tag,
|
|
165
|
+
children: [],
|
|
166
|
+
textStart: pos
|
|
167
|
+
};
|
|
168
|
+
parent.children.push(newNode);
|
|
169
|
+
stack.push(newNode);
|
|
170
|
+
} else stack.pop();
|
|
171
|
+
lastPos = pos;
|
|
172
|
+
}
|
|
173
|
+
if (lastPos < text.length) stack[stack.length - 1].children.push(text.slice(lastPos));
|
|
174
|
+
return root;
|
|
175
|
+
}
|
|
176
|
+
function $156a3efbc315814c$var$renderNode(node, dispatch, selectedNodes, parentSelected) {
|
|
177
|
+
if (typeof node === "string") return node;
|
|
178
|
+
const { tag: tag, children: children } = node;
|
|
179
|
+
const isSelected = selectedNodes?.includes(tag.id);
|
|
180
|
+
const showBorder = selectedNodes.length === 0 || isSelected;
|
|
181
|
+
const style = {
|
|
182
|
+
...tag,
|
|
183
|
+
zIndex: parentSelected ? -1 : 1,
|
|
184
|
+
border: "1px solid " + (showBorder ? tag.color : "transparent"),
|
|
185
|
+
margin: "-1px"
|
|
186
|
+
};
|
|
187
|
+
let moveText = [];
|
|
188
|
+
if (isSelected) {
|
|
189
|
+
for(const key in children)if (Object.prototype.hasOwnProperty.call(children, key)) {
|
|
190
|
+
const child = children[key];
|
|
191
|
+
if (child?.tag) moveText.push(child.children[0]);
|
|
192
|
+
else moveText.push(child);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
return $156a3efbc315814c$var$h("span", {
|
|
196
|
+
className: "highlight",
|
|
197
|
+
style: style,
|
|
198
|
+
onClick: (e)=>{
|
|
199
|
+
e.stopPropagation();
|
|
200
|
+
if (e.ctrlKey || e.metaKey || selectedNodes[0] === tag.id && selectedNodes.length === 1) {
|
|
201
|
+
// Toggle selection on ctrl/cmd click or when node is only selected node
|
|
202
|
+
e.stopPropagation();
|
|
203
|
+
dispatch({
|
|
204
|
+
type: "toggle-node-selected",
|
|
205
|
+
payload: {
|
|
206
|
+
ids: [
|
|
207
|
+
tag.id
|
|
208
|
+
]
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
} else if (e.shiftKey && selectedNodes.length > 0) {
|
|
212
|
+
// Select range from last selected node to this one
|
|
213
|
+
const lastSelected = selectedNodes[selectedNodes.length - 1];
|
|
214
|
+
dispatch({
|
|
215
|
+
type: "select-range",
|
|
216
|
+
payload: {
|
|
217
|
+
ids: [
|
|
218
|
+
lastSelected,
|
|
219
|
+
tag.id
|
|
220
|
+
]
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
} else dispatch({
|
|
224
|
+
type: "select-node",
|
|
225
|
+
payload: {
|
|
226
|
+
ids: [
|
|
227
|
+
tag.id
|
|
228
|
+
]
|
|
229
|
+
}
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
}, isSelected ? moveText.flat() : children.map((child, i)=>$156a3efbc315814c$var$renderNode(child, dispatch, selectedNodes, isSelected)));
|
|
233
|
+
}
|
|
234
|
+
function $156a3efbc315814c$export$190465bec6b893be(props) {
|
|
235
|
+
const { text: text, allTags: allTags = [], dispatch: dispatch, selectedNodes: selectedNodes, allowOverlap: allowOverlap } = props;
|
|
236
|
+
const tree = $156a3efbc315814c$var$nestHighlights(text, allTags);
|
|
237
|
+
const spanRef = (0, $aogpP$useRef)(null);
|
|
238
|
+
(0, $aogpP$useEffect)(()=>{
|
|
239
|
+
const handleMouseUp = ()=>{
|
|
240
|
+
const tag = $156a3efbc315814c$var$createTagFromSelection({
|
|
241
|
+
container: spanRef.current
|
|
242
|
+
});
|
|
243
|
+
if (!tag) return;
|
|
244
|
+
$156a3efbc315814c$var$addTag({
|
|
245
|
+
tag: tag,
|
|
246
|
+
dispatch: dispatch,
|
|
247
|
+
text: text,
|
|
248
|
+
allTags: allTags,
|
|
249
|
+
allowOverlap: allowOverlap
|
|
250
|
+
});
|
|
251
|
+
};
|
|
252
|
+
document.addEventListener("mouseup", handleMouseUp);
|
|
253
|
+
return ()=>{
|
|
254
|
+
document.removeEventListener("mouseup", handleMouseUp);
|
|
255
|
+
};
|
|
256
|
+
}, [
|
|
257
|
+
text,
|
|
258
|
+
allTags,
|
|
259
|
+
dispatch,
|
|
260
|
+
allowOverlap
|
|
261
|
+
]);
|
|
262
|
+
return $156a3efbc315814c$var$h("span", {
|
|
263
|
+
ref: spanRef
|
|
264
|
+
}, tree.children.map((child, i)=>$156a3efbc315814c$var$renderNode(child, dispatch, selectedNodes, false)));
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
export {$156a3efbc315814c$export$6e107db9091b8219 as FeedbackText, $156a3efbc315814c$export$190465bec6b893be as HighlightedText};
|
|
269
|
+
//# sourceMappingURL=feedback-components.46a7a347.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"mappings":"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","sources":["packages/feedback-components/src/feedback/text-visualizer.ts"],"sourcesContent":["import { AnnotateBlendTag } from \"react-text-annotate-blend\";\nimport { InternalEntity } from \"./types\";\nimport { TreeDispatch } from \"./edit-state\";\nimport styles from \"./feedback.module.sass\";\nimport hyper from \"@macrostrat/hyper\";\nimport { buildHighlights, getTagStyle } from \"../extractions\";\nimport { Highlight } from \"../extractions/types\";\nimport { useEffect, useRef } from \"react\";\n\nconst h = hyper.styled(styles);\n\nexport interface FeedbackTextProps {\n text: string;\n selectedNodes: number[];\n nodes: InternalEntity[];\n updateNodes: (nodes: string[]) => void;\n dispatch: TreeDispatch;\n lineHeight: string;\n allowOverlap?: boolean;\n}\n\nfunction buildTags(\n highlights: Highlight[],\n selectedNodes: number[],\n): AnnotateBlendTag[] {\n let tags: AnnotateBlendTag[] = [];\n // If entity ID has already been seen, don't add it again\n const entities = new Set<number>();\n\n for (const highlight of highlights) {\n // Don't add multiply-linked entities multiple times\n if (entities.has(highlight.id)) continue;\n\n const highlighted = isHighlighted(highlight, selectedNodes);\n const active = isActive(highlight, selectedNodes);\n const tagStyle = getTagStyle(highlight.backgroundColor, {\n highlighted,\n active,\n });\n\n const tag = {\n color: tagStyle.color,\n tagStyle: {\n display: \"none\",\n },\n markStyle: {\n backgroundColor: tagStyle.backgroundColor,\n },\n ...highlight,\n backgroundColor: tagStyle.backgroundColor,\n };\n\n tags.push(tag);\n\n entities.add(highlight.id);\n }\n\n return tags;\n}\n\nfunction isActive(tag: Highlight, selectedNodes: number[]) {\n return selectedNodes.includes(tag.id);\n}\n\nfunction isHighlighted(tag: Highlight, selectedNodes: number[]) {\n if (selectedNodes.length === 0) return true;\n return (\n (selectedNodes.includes(tag.id) ||\n tag.parents?.some((d) => selectedNodes.includes(d))) ??\n false\n );\n}\n\nexport function FeedbackText(props: FeedbackTextProps) {\n // Convert input to tags\n const { text, selectedNodes, nodes, dispatch, allowOverlap } = props;\n const allTags: AnnotateBlendTag[] = buildTags(\n buildHighlights(nodes, null),\n selectedNodes,\n );\n\n return h(\n \"div.feedback-text-wrapper\",\n {\n tabIndex: 0,\n onKeyDown: (e) => {\n if (e.key === \"Backspace\") {\n dispatch({\n type: \"delete-node\",\n payload: { ids: selectedNodes },\n });\n }\n },\n },\n h(HighlightedText, {\n text,\n allTags,\n allowOverlap,\n dispatch,\n selectedNodes,\n }),\n );\n}\n\nfunction createTagFromSelection({\n container,\n}: {\n container: HTMLElement | null;\n}) {\n const selection = window.getSelection();\n if (\n !selection ||\n selection.isCollapsed ||\n selection.rangeCount === 0 ||\n !container\n )\n return null;\n\n const range = selection.getRangeAt(0);\n\n if (\n !container.contains(range.startContainer) ||\n !container.contains(range.endContainer)\n ) {\n return null;\n }\n\n const preRange = document.createRange();\n preRange.setStart(container, 0);\n preRange.setEnd(range.startContainer, range.startOffset);\n const start = preRange.toString().length;\n\n const selectedText = range.toString();\n const end = start + selectedText.length;\n\n return {\n start,\n end,\n text: selectedText,\n };\n}\n\nfunction addTag({ tag, dispatch, text, allTags, allowOverlap }) {\n let { start, end } = tag;\n // snap to text\n if (text[end - 1] != \" \") {\n // double clicking word overselects by one, shouldn't increase to next word\n while (start > 0 && /\\w/.test(text[start - 1])) {\n start--;\n }\n while (end < text.length && /\\w/.test(text[end])) {\n end++;\n }\n }\n\n let payload = { start, end, text: text.slice(start, end) };\n\n if (payload.text.trim() === \"\") {\n console.log(\"Blank tag found, ignoring\");\n return;\n }\n\n const duplicate = allTags.find(\n (t) =>\n t.start === payload.start &&\n (t.end === payload.end || t.end === payload.end - 1),\n );\n\n if (duplicate) {\n console.log(\"Duplicate tag found, ignoring\");\n return;\n }\n\n if (payload.text.endsWith(\" \")) {\n payload.text = payload.text.slice(0, -1);\n payload.end -= 1;\n }\n\n const inside = allTags.some(\n (t) => t.start <= payload.start && t.end >= payload.end,\n );\n\n const overlap = allTags.some(\n (t) => t.start < payload.end && t.end > payload.start,\n );\n\n if ((inside || overlap) && !allowOverlap) {\n console.log(\"Tag is inside another tag, ignoring\");\n return;\n }\n\n dispatch({ type: \"create-node\", payload });\n}\n\nfunction nestHighlights(text: string, tags: AnnotateBlendTag[]) {\n const events: Array<{\n pos: number;\n type: \"start\" | \"end\";\n tag: AnnotateBlendTag;\n }> = [];\n\n for (const tag of tags) {\n events.push({ pos: tag.start, type: \"start\", tag });\n events.push({ pos: tag.end, type: \"end\", tag });\n }\n\n events.sort((a, b) => {\n if (a.pos !== b.pos) return a.pos - b.pos;\n if (a.type === \"end\" && b.type === \"start\") return -1;\n if (a.type === \"start\" && b.type === \"end\") return 1;\n return 0;\n });\n\n const root = { children: [], textStart: 0 };\n const stack = [root];\n let lastPos = 0;\n\n for (const { pos, type, tag } of events) {\n const parent = stack[stack.length - 1];\n\n if (pos > lastPos) {\n const slice = text.slice(lastPos, pos);\n parent.children.push(slice);\n }\n\n if (type === \"start\") {\n const newNode = { tag, children: [], textStart: pos };\n parent.children.push(newNode);\n stack.push(newNode);\n } else {\n stack.pop();\n }\n\n lastPos = pos;\n }\n\n if (lastPos < text.length) {\n stack[stack.length - 1].children.push(text.slice(lastPos));\n }\n\n return root;\n}\n\nfunction renderNode(\n node: any,\n dispatch: TreeDispatch,\n selectedNodes: number[],\n parentSelected: boolean,\n): any {\n if (typeof node === \"string\") return node;\n\n const { tag, children } = node;\n const isSelected = selectedNodes?.includes(tag.id);\n const showBorder = selectedNodes.length === 0 || isSelected;\n\n const style = {\n ...tag,\n zIndex: parentSelected ? -1 : 1,\n border: \"1px solid \" + (showBorder ? tag.color : \"transparent\"),\n margin: \"-1px\",\n };\n\n let moveText = [];\n if (isSelected) {\n for (const key in children) {\n if (Object.prototype.hasOwnProperty.call(children, key)) {\n const child = children[key];\n if (child?.tag) {\n moveText.push(child.children[0]);\n } else {\n moveText.push(child);\n }\n }\n }\n }\n\n return h(\n \"span\",\n {\n className: \"highlight\",\n style,\n onClick: (e: MouseEvent) => {\n e.stopPropagation();\n if (\n e.ctrlKey ||\n e.metaKey ||\n (selectedNodes[0] === tag.id && selectedNodes.length === 1)\n ) {\n // Toggle selection on ctrl/cmd click or when node is only selected node\n e.stopPropagation();\n dispatch({\n type: \"toggle-node-selected\",\n payload: { ids: [tag.id] },\n });\n } else if (e.shiftKey && selectedNodes.length > 0) {\n // Select range from last selected node to this one\n const lastSelected = selectedNodes[selectedNodes.length - 1];\n\n dispatch({\n type: \"select-range\",\n payload: { ids: [lastSelected, tag.id] },\n });\n } else {\n dispatch({\n type: \"select-node\",\n payload: { ids: [tag.id] },\n });\n }\n },\n },\n isSelected\n ? moveText.flat()\n : children.map((child: any, i: number) =>\n renderNode(child, dispatch, selectedNodes, isSelected),\n ),\n );\n}\n\nexport function HighlightedText(props: {\n text: string;\n allTags: AnnotateBlendTag[];\n lineHeight: string;\n allowOverlap?: boolean;\n dispatch: TreeDispatch;\n selectedNodes: number[];\n}) {\n const { text, allTags = [], dispatch, selectedNodes, allowOverlap } = props;\n\n const tree = nestHighlights(text, allTags);\n\n const spanRef = useRef<HTMLSpanElement>(null);\n\n useEffect(() => {\n const handleMouseUp = () => {\n const tag = createTagFromSelection({ container: spanRef.current });\n if (!tag) return;\n addTag({ tag, dispatch, text, allTags, allowOverlap });\n };\n\n document.addEventListener(\"mouseup\", handleMouseUp);\n return () => {\n document.removeEventListener(\"mouseup\", handleMouseUp);\n };\n }, [text, allTags, dispatch, allowOverlap]);\n\n return h(\n \"span\",\n { ref: spanRef },\n tree.children.map((child: any, i: number) =>\n renderNode(child, dispatch, selectedNodes, false),\n ),\n );\n}\n"],"names":[],"version":3,"file":"feedback-components.46a7a347.js.map"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {EntityTag as $03d8811e9c9b360d$export$117e56c71b172cde} from "./
|
|
2
|
-
import {useTreeDispatch as $b79bf29960412ca7$export$e1068f2d1c68f87e} from "./
|
|
3
|
-
import "./feedback.
|
|
4
|
-
import $gIldz$
|
|
1
|
+
import {EntityTag as $03d8811e9c9b360d$export$117e56c71b172cde} from "./feedback-components.5df2a926.js";
|
|
2
|
+
import {useTreeDispatch as $b79bf29960412ca7$export$e1068f2d1c68f87e} from "./feedback-components.fa1d3641.js";
|
|
3
|
+
import "./feedback-components.fb60c70d.css";
|
|
4
|
+
import $gIldz$feedbackcomponents95dbe7d7js from "./feedback-components.95dbe7d7.js";
|
|
5
5
|
import $gIldz$macrostrathyper from "@macrostrat/hyper";
|
|
6
6
|
|
|
7
7
|
|
|
@@ -12,7 +12,7 @@ function $parcel$interopDefault(a) {
|
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
|
|
15
|
-
const $b6b9741bf83336eb$var$h = (0, $gIldz$macrostrathyper).styled((0, ($parcel$interopDefault($gIldz$
|
|
15
|
+
const $b6b9741bf83336eb$var$h = (0, $gIldz$macrostrathyper).styled((0, ($parcel$interopDefault($gIldz$feedbackcomponents95dbe7d7js))));
|
|
16
16
|
function $b6b9741bf83336eb$var$isSelected(searchNode, treeNode) {
|
|
17
17
|
return searchNode.id == treeNode.id;
|
|
18
18
|
// We could also select children of the search node here if we wanted to
|
|
@@ -37,6 +37,11 @@ function $b6b9741bf83336eb$var$Node({ node: node, style: style, dragHandle: drag
|
|
|
37
37
|
let highlighted = $b6b9741bf83336eb$var$isNodeHighlighted(node, tree);
|
|
38
38
|
let active = $b6b9741bf83336eb$var$isNodeActive(node, tree);
|
|
39
39
|
const dispatch = (0, $b79bf29960412ca7$export$e1068f2d1c68f87e)();
|
|
40
|
+
// console.log("Node render", node.data, highlighted, active);
|
|
41
|
+
if (!node.data?.type) node.data.type = {
|
|
42
|
+
name: "lith",
|
|
43
|
+
color: "rgb(107, 255, 91)"
|
|
44
|
+
};
|
|
40
45
|
return $b6b9741bf83336eb$var$h("div.node", {
|
|
41
46
|
style: style,
|
|
42
47
|
ref: dragHandle
|
|
@@ -56,4 +61,4 @@ var $b6b9741bf83336eb$export$2e2bcd8739ae039 = $b6b9741bf83336eb$var$Node;
|
|
|
56
61
|
|
|
57
62
|
|
|
58
63
|
export {$b6b9741bf83336eb$export$2e2bcd8739ae039 as default};
|
|
59
|
-
//# sourceMappingURL=
|
|
64
|
+
//# sourceMappingURL=feedback-components.5509fab3.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"mappings":";;;;;;;;;;;;;;AAOA,MAAM,0BAAI,CAAA,GAAA,sBAAI,EAAE,MAAM,CAAC,CAAA,GAAA,8EAAK;AAE5B,SAAS,iCAAW,UAAoB,EAAE,QAAkB;IAC1D,OAAO,WAAW,EAAE,IAAI,SAAS,EAAE;AACnC,wEAAwE;AAC1E;AAEA,SAAS,wCAAkB,IAAuB,EAAE,IAAuB;IACzE,gFAAgF;IAChF,IAAI,KAAK,aAAa,CAAC,MAAM,IAAI,GAC/B,OAAO;IAGT,KAAK,MAAM,gBAAgB,KAAK,aAAa,CAAE;QAC7C,IAAI,iCAAW,KAAK,IAAI,EAAE,aAAa,IAAI,GACzC,OAAO;IAEX;IAEA,0CAA0C;IAC1C,IAAI,KAAK,MAAM,IAAI,QAAQ,wCAAkB,KAAK,MAAM,EAAE,OACxD,OAAO;IAGT,OAAO;AACT;AAEA,SAAS,mCAAa,IAAuB,EAAE,IAAuB;IACpE,KAAK,MAAM,gBAAgB,KAAK,aAAa,CAAE;QAC7C,IAAI,iCAAW,KAAK,IAAI,EAAE,aAAa,IAAI,GACzC,OAAO;IAEX;IACA,OAAO;AACT;AAEA,SAAS,2BAAK,QAAE,IAAI,SAAE,KAAK,cAAE,UAAU,QAAE,IAAI,kBAAE,cAAc,EAAO;IAClE,IAAI,cAAuB,wCAAkB,MAAM;IACnD,IAAI,SAAkB,mCAAa,MAAM;IAEzC,MAAM,WAAW,CAAA,GAAA,yCAAc;IAE/B,8DAA8D;IAE9D,IAAI,CAAC,KAAK,IAAI,EAAE,MACd,KAAK,IAAI,CAAC,IAAI,GAAG;QAAE,MAAM;QAAQ,OAAO;IAAoB;IAG9D,OAAO,wBACL,YACA;eAAE;QAAO,KAAK;IAAW,GACzB,wBAAE,CAAA,GAAA,yCAAQ,GAAG;QACX,MAAM,KAAK,IAAI;gBACf;qBACA;wBACA;QACA;YACE,SAAS;gBAAE,MAAM;YAA8B;QACjD;IACF;AAEJ;IAEA,2CAAe","sources":["packages/feedback-components/src/feedback/node.ts"],"sourcesContent":["import { NodeApi, TreeApi } from \"react-arborist\";\nimport { TreeData } from \"./types\";\nimport { EntityTag } from \"../extractions\";\nimport { useTreeDispatch } from \"./edit-state\";\nimport styles from \"./feedback.module.sass\";\nimport hyper from \"@macrostrat/hyper\";\n\nconst h = hyper.styled(styles);\n\nfunction isSelected(searchNode: TreeData, treeNode: TreeData) {\n return searchNode.id == treeNode.id;\n // We could also select children of the search node here if we wanted to\n}\n\nfunction isNodeHighlighted(node: NodeApi<TreeData>, tree: TreeApi<TreeData>) {\n // We treat no selection as all nodes being active. We may add some nuance later\n if (tree.selectedNodes.length == 0) {\n return true;\n }\n\n for (const selectedNode of tree.selectedNodes) {\n if (isSelected(node.data, selectedNode.data)) {\n return true;\n }\n }\n\n // Check if the parent node is highlighted\n if (node.parent != null && isNodeHighlighted(node.parent, tree)) {\n return true;\n }\n\n return false;\n}\n\nfunction isNodeActive(node: NodeApi<TreeData>, tree: TreeApi<TreeData>) {\n for (const selectedNode of tree.selectedNodes) {\n if (isSelected(node.data, selectedNode.data)) {\n return true;\n }\n }\n return false;\n}\n\nfunction Node({ node, style, dragHandle, tree, matchComponent }: any) {\n let highlighted: boolean = isNodeHighlighted(node, tree);\n let active: boolean = isNodeActive(node, tree);\n\n const dispatch = useTreeDispatch();\n\n // console.log(\"Node render\", node.data, highlighted, active);\n\n if (!node.data?.type) {\n node.data.type = { name: \"lith\", color: \"rgb(107, 255, 91)\" };\n }\n\n return h(\n \"div.node\",\n { style, ref: dragHandle },\n h(EntityTag, {\n data: node.data,\n active,\n highlighted,\n matchComponent,\n onClickType() {\n dispatch({ type: \"toggle-entity-type-selector\" });\n },\n }),\n );\n}\n\nexport default Node;\n"],"names":[],"version":3,"file":"feedback-components.5509fab3.js.map"}
|