@macrostrat/feedback-components 1.1.0 → 1.1.2
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 +20 -0
- package/dist/esm/{feedback-components.7cd9b6cc.js → feedback-components.3b3a5357.js} +53 -30
- package/dist/esm/feedback-components.3b3a5357.js.map +1 -0
- package/dist/esm/{feedback-components.921dcd46.js → feedback-components.46a7a347.js} +42 -14
- package/dist/esm/feedback-components.46a7a347.js.map +1 -0
- package/dist/esm/{feedback-components.87533431.js → feedback-components.5509fab3.js} +5 -5
- package/dist/esm/{feedback-components.87533431.js.map → feedback-components.5509fab3.js.map} +1 -1
- package/dist/esm/{feedback-components.6a6c8af5.js → feedback-components.586103e8.js} +108 -82
- package/dist/esm/feedback-components.586103e8.js.map +1 -0
- package/dist/esm/{feedback-components.4359bc80.js → feedback-components.95dbe7d7.js} +13 -1
- package/dist/esm/feedback-components.95dbe7d7.js.map +1 -0
- package/dist/esm/{feedback-components.bf5f7cf7.js → feedback-components.fa1d3641.js} +29 -2
- package/dist/esm/feedback-components.fa1d3641.js.map +1 -0
- package/dist/esm/{feedback-components.b7d9b015.css → feedback-components.fb60c70d.css} +38 -14
- package/dist/esm/feedback-components.fb60c70d.css.map +1 -0
- package/dist/esm/index.d.ts +3 -82
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +1 -1
- 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/{feedback-components.e8aa70b8.js → feedback-components.a39f7653.js} +2 -2
- package/dist/node/{feedback-components.e8aa70b8.js.map → feedback-components.a39f7653.js.map} +1 -1
- 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 +3 -3
- package/src/feedback/edit-state.ts +41 -3
- package/src/feedback/feedback.module.sass +30 -10
- package/src/feedback/graph.ts +27 -10
- package/src/feedback/index.ts +146 -112
- package/src/feedback/text-visualizer.ts +43 -17
- package/dist/esm/feedback-components.4359bc80.js.map +0 -1
- package/dist/esm/feedback-components.6a6c8af5.js.map +0 -1
- package/dist/esm/feedback-components.7cd9b6cc.js.map +0 -1
- package/dist/esm/feedback-components.921dcd46.js.map +0 -1
- package/dist/esm/feedback-components.b7d9b015.css.map +0 -1
- package/dist/esm/feedback-components.bf5f7cf7.js.map +0 -1
- package/dist/node/feedback-components.15e1316d.js +0 -2
- package/dist/node/feedback-components.15e1316d.js.map +0 -1
- package/dist/node/feedback-components.65d8488e.js +0 -2
- package/dist/node/feedback-components.65d8488e.js.map +0 -1
- package/dist/node/feedback-components.6681dbde.js +0 -2
- package/dist/node/feedback-components.6681dbde.js.map +0 -1
- package/dist/node/feedback-components.77b6fc89.css +0 -2
- package/dist/node/feedback-components.77b6fc89.css.map +0 -1
- package/dist/node/feedback-components.7caa447a.js +0 -2
- package/dist/node/feedback-components.7caa447a.js.map +0 -1
- package/dist/node/feedback-components.e2f3c4b7.js +0 -2
- package/dist/node/feedback-components.e2f3c4b7.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,26 @@ 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.2] - 2025-07-10
|
|
8
|
+
|
|
9
|
+
- Increased the default line spacing in the paragraph text (made it configurable
|
|
10
|
+
via a CSS variable)
|
|
11
|
+
- Added a toggle in the graph view to show labels for all nodes, and made nodes
|
|
12
|
+
slightly bigger
|
|
13
|
+
- Unified selection interactions
|
|
14
|
+
- Updated tags in the "select list" on the right to have styling for
|
|
15
|
+
selected/unselected states consistent with the rest of the interface
|
|
16
|
+
- Added "assistant panel" style entity types selector
|
|
17
|
+
- Added a border to selected tags in the paragraph area, similar to the list
|
|
18
|
+
view
|
|
19
|
+
- Snapped tag selections to word boundaries
|
|
20
|
+
|
|
21
|
+
## [1.1.1] - 2025-07-01
|
|
22
|
+
|
|
23
|
+
- new text component, following same clicking rules as tree
|
|
24
|
+
- Entity panel updates
|
|
25
|
+
- Entity types are editable, deletable, and addable
|
|
26
|
+
|
|
7
27
|
## [1.1.0] - 2025-06-25
|
|
8
28
|
|
|
9
29
|
Major updates by David Sklar to improve usability
|
|
@@ -1,24 +1,33 @@
|
|
|
1
|
-
import {treeToGraph as $b79bf29960412ca7$export$8d9dbb7a64bf2a5e} from "./feedback-components.
|
|
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";
|
|
2
4
|
import {getTagStyle as $03d8811e9c9b360d$export$35baa338324d8550} from "./feedback-components.5df2a926.js";
|
|
3
5
|
import $phGch$macrostrathyper from "@macrostrat/hyper";
|
|
4
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";
|
|
5
7
|
import {useState as $phGch$useState, useEffect as $phGch$useEffect} from "react";
|
|
6
|
-
import {Spinner as $phGch$Spinner} from "@blueprintjs/core";
|
|
8
|
+
import {Spinner as $phGch$Spinner, Switch as $phGch$Switch} from "@blueprintjs/core";
|
|
7
9
|
import {ErrorBoundary as $phGch$ErrorBoundary} from "@macrostrat/ui-components";
|
|
8
10
|
|
|
9
11
|
|
|
12
|
+
function $parcel$interopDefault(a) {
|
|
13
|
+
return a && a.__esModule ? a.default : a;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
|
|
10
17
|
|
|
11
18
|
|
|
12
19
|
|
|
13
20
|
|
|
14
21
|
|
|
15
22
|
|
|
23
|
+
const $ff8c3e7f2bc22925$var$h = (0, $phGch$macrostrathyper).styled((0, ($parcel$interopDefault($phGch$feedbackcomponents95dbe7d7js))));
|
|
16
24
|
function $ff8c3e7f2bc22925$export$6a7fe3ef90e8d566(props) {
|
|
17
25
|
// A graph view with react-flow
|
|
18
26
|
// Get positions of nodes using force simulation
|
|
19
27
|
const { tree: tree, width: width, height: height, dispatch: dispatch, selectedNodes: selectedNodes } = props;
|
|
20
28
|
const [nodes, setNodes] = (0, $phGch$useState)(null);
|
|
21
29
|
const [links, setLinks] = (0, $phGch$useState)(null);
|
|
30
|
+
const [showLabels, setShowLabels] = (0, $phGch$useState)(false);
|
|
22
31
|
(0, $phGch$useEffect)(()=>{
|
|
23
32
|
const { nodes: nodes, edges: edges } = (0, $b79bf29960412ca7$export$8d9dbb7a64bf2a5e)(tree);
|
|
24
33
|
const nodesMap = new Map(nodes.map((d)=>[
|
|
@@ -49,22 +58,28 @@ function $ff8c3e7f2bc22925$export$6a7fe3ef90e8d566(props) {
|
|
|
49
58
|
width,
|
|
50
59
|
height
|
|
51
60
|
]);
|
|
52
|
-
if (nodes == null || links == null) return
|
|
61
|
+
if (nodes == null || links == null) return $ff8c3e7f2bc22925$var$h((0, $phGch$Spinner));
|
|
53
62
|
console.log("Graph", nodes, links, selectedNodes);
|
|
54
|
-
return
|
|
63
|
+
return $ff8c3e7f2bc22925$var$h((0, $phGch$ErrorBoundary), {
|
|
55
64
|
description: "An error occurred while rendering the graph view."
|
|
56
|
-
},
|
|
65
|
+
}, $ff8c3e7f2bc22925$var$h("div.graph-view", {
|
|
57
66
|
style: {
|
|
58
67
|
width: width,
|
|
59
68
|
height: height
|
|
60
69
|
}
|
|
61
70
|
}, [
|
|
62
|
-
(0, $phGch$
|
|
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", {
|
|
63
78
|
width: width,
|
|
64
79
|
height: height
|
|
65
80
|
}, [
|
|
66
|
-
|
|
67
|
-
return
|
|
81
|
+
$ff8c3e7f2bc22925$var$h("g.links", links.map((d)=>{
|
|
82
|
+
return $ff8c3e7f2bc22925$var$h("line", {
|
|
68
83
|
x1: d.source.x,
|
|
69
84
|
y1: d.source.y,
|
|
70
85
|
x2: d.target.x,
|
|
@@ -72,7 +87,7 @@ function $ff8c3e7f2bc22925$export$6a7fe3ef90e8d566(props) {
|
|
|
72
87
|
stroke: "black"
|
|
73
88
|
});
|
|
74
89
|
})),
|
|
75
|
-
|
|
90
|
+
$ff8c3e7f2bc22925$var$h("g.nodes", nodes.map((d)=>{
|
|
76
91
|
const active = selectedNodes.includes(d.id);
|
|
77
92
|
const stroke = active ? "white" : "black";
|
|
78
93
|
const highlighted = $ff8c3e7f2bc22925$var$isHighlighted(d.id, selectedNodes, nodes);
|
|
@@ -80,26 +95,34 @@ function $ff8c3e7f2bc22925$export$6a7fe3ef90e8d566(props) {
|
|
|
80
95
|
highlighted: highlighted,
|
|
81
96
|
active: active
|
|
82
97
|
});
|
|
83
|
-
return
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
e
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
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
|
+
]);
|
|
103
126
|
}))
|
|
104
127
|
])
|
|
105
128
|
]));
|
|
@@ -111,4 +134,4 @@ function $ff8c3e7f2bc22925$var$isHighlighted(id, selectedNodes, nodes) {
|
|
|
111
134
|
|
|
112
135
|
|
|
113
136
|
export {$ff8c3e7f2bc22925$export$6a7fe3ef90e8d566 as GraphView};
|
|
114
|
-
//# sourceMappingURL=feedback-components.
|
|
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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import "./feedback-components.
|
|
2
|
-
import $aogpP$
|
|
1
|
+
import "./feedback-components.fb60c70d.css";
|
|
2
|
+
import $aogpP$feedbackcomponents95dbe7d7js from "./feedback-components.95dbe7d7.js";
|
|
3
3
|
import {buildHighlights as $03d8811e9c9b360d$export$c4b91360064ad200, getTagStyle as $03d8811e9c9b360d$export$35baa338324d8550} from "./feedback-components.5df2a926.js";
|
|
4
4
|
import $aogpP$macrostrathyper from "@macrostrat/hyper";
|
|
5
5
|
import {useRef as $aogpP$useRef, useEffect as $aogpP$useEffect} from "react";
|
|
@@ -12,7 +12,7 @@ function $parcel$interopDefault(a) {
|
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
|
|
15
|
-
const $156a3efbc315814c$var$h = (0, $aogpP$macrostrathyper).styled((0, ($parcel$interopDefault($aogpP$
|
|
15
|
+
const $156a3efbc315814c$var$h = (0, $aogpP$macrostrathyper).styled((0, ($parcel$interopDefault($aogpP$feedbackcomponents95dbe7d7js))));
|
|
16
16
|
function $156a3efbc315814c$var$buildTags(highlights, selectedNodes) {
|
|
17
17
|
let tags = [];
|
|
18
18
|
// If entity ID has already been seen, don't add it again
|
|
@@ -51,7 +51,7 @@ function $156a3efbc315814c$var$isHighlighted(tag, selectedNodes) {
|
|
|
51
51
|
}
|
|
52
52
|
function $156a3efbc315814c$export$6e107db9091b8219(props) {
|
|
53
53
|
// Convert input to tags
|
|
54
|
-
const { text: text, selectedNodes: selectedNodes, nodes: nodes, dispatch: dispatch,
|
|
54
|
+
const { text: text, selectedNodes: selectedNodes, nodes: nodes, dispatch: dispatch, allowOverlap: allowOverlap } = props;
|
|
55
55
|
const allTags = $156a3efbc315814c$var$buildTags((0, $03d8811e9c9b360d$export$c4b91360064ad200)(nodes, null), selectedNodes);
|
|
56
56
|
return $156a3efbc315814c$var$h("div.feedback-text-wrapper", {
|
|
57
57
|
tabIndex: 0,
|
|
@@ -66,7 +66,6 @@ function $156a3efbc315814c$export$6e107db9091b8219(props) {
|
|
|
66
66
|
}, $156a3efbc315814c$var$h($156a3efbc315814c$export$190465bec6b893be, {
|
|
67
67
|
text: text,
|
|
68
68
|
allTags: allTags,
|
|
69
|
-
lineHeight: lineHeight,
|
|
70
69
|
allowOverlap: allowOverlap,
|
|
71
70
|
dispatch: dispatch,
|
|
72
71
|
selectedNodes: selectedNodes
|
|
@@ -90,7 +89,13 @@ function $156a3efbc315814c$var$createTagFromSelection({ container: container })
|
|
|
90
89
|
};
|
|
91
90
|
}
|
|
92
91
|
function $156a3efbc315814c$var$addTag({ tag: tag, dispatch: dispatch, text: text, allTags: allTags, allowOverlap: allowOverlap }) {
|
|
93
|
-
|
|
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
|
+
}
|
|
94
99
|
let payload = {
|
|
95
100
|
start: start,
|
|
96
101
|
end: end,
|
|
@@ -172,9 +177,12 @@ function $156a3efbc315814c$var$renderNode(node, dispatch, selectedNodes, parentS
|
|
|
172
177
|
if (typeof node === "string") return node;
|
|
173
178
|
const { tag: tag, children: children } = node;
|
|
174
179
|
const isSelected = selectedNodes?.includes(tag.id);
|
|
180
|
+
const showBorder = selectedNodes.length === 0 || isSelected;
|
|
175
181
|
const style = {
|
|
176
182
|
...tag,
|
|
177
|
-
zIndex: parentSelected ? -1 : 1
|
|
183
|
+
zIndex: parentSelected ? -1 : 1,
|
|
184
|
+
border: "1px solid " + (showBorder ? tag.color : "transparent"),
|
|
185
|
+
margin: "-1px"
|
|
178
186
|
};
|
|
179
187
|
let moveText = [];
|
|
180
188
|
if (isSelected) {
|
|
@@ -189,8 +197,31 @@ function $156a3efbc315814c$var$renderNode(node, dispatch, selectedNodes, parentS
|
|
|
189
197
|
style: style,
|
|
190
198
|
onClick: (e)=>{
|
|
191
199
|
e.stopPropagation();
|
|
192
|
-
|
|
193
|
-
|
|
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",
|
|
194
225
|
payload: {
|
|
195
226
|
ids: [
|
|
196
227
|
tag.id
|
|
@@ -201,7 +232,7 @@ function $156a3efbc315814c$var$renderNode(node, dispatch, selectedNodes, parentS
|
|
|
201
232
|
}, isSelected ? moveText.flat() : children.map((child, i)=>$156a3efbc315814c$var$renderNode(child, dispatch, selectedNodes, isSelected)));
|
|
202
233
|
}
|
|
203
234
|
function $156a3efbc315814c$export$190465bec6b893be(props) {
|
|
204
|
-
const { text: text, allTags: allTags = [],
|
|
235
|
+
const { text: text, allTags: allTags = [], dispatch: dispatch, selectedNodes: selectedNodes, allowOverlap: allowOverlap } = props;
|
|
205
236
|
const tree = $156a3efbc315814c$var$nestHighlights(text, allTags);
|
|
206
237
|
const spanRef = (0, $aogpP$useRef)(null);
|
|
207
238
|
(0, $aogpP$useEffect)(()=>{
|
|
@@ -229,13 +260,10 @@ function $156a3efbc315814c$export$190465bec6b893be(props) {
|
|
|
229
260
|
allowOverlap
|
|
230
261
|
]);
|
|
231
262
|
return $156a3efbc315814c$var$h("span", {
|
|
232
|
-
style: {
|
|
233
|
-
lineHeight: lineHeight
|
|
234
|
-
},
|
|
235
263
|
ref: spanRef
|
|
236
264
|
}, tree.children.map((child, i)=>$156a3efbc315814c$var$renderNode(child, dispatch, selectedNodes, false)));
|
|
237
265
|
}
|
|
238
266
|
|
|
239
267
|
|
|
240
268
|
export {$156a3efbc315814c$export$6e107db9091b8219 as FeedbackText, $156a3efbc315814c$export$190465bec6b893be as HighlightedText};
|
|
241
|
-
//# sourceMappingURL=feedback-components.
|
|
269
|
+
//# sourceMappingURL=feedback-components.46a7a347.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"mappings":";;;;;;;;;;;;;;AASA,MAAM,0BAAI,CAAA,GAAA,sBAAI,EAAE,MAAM,CAAC,CAAA,GAAA,8EAAK;AAY5B,SAAS,gCACP,UAAuB,EACvB,aAAuB;IAEvB,IAAI,OAA2B,EAAE;IACjC,yDAAyD;IACzD,MAAM,WAAW,IAAI;IAErB,KAAK,MAAM,aAAa,WAAY;QAClC,oDAAoD;QACpD,IAAI,SAAS,GAAG,CAAC,UAAU,EAAE,GAAG;QAEhC,MAAM,cAAc,oCAAc,WAAW;QAC7C,MAAM,SAAS,+BAAS,WAAW;QACnC,MAAM,WAAW,CAAA,GAAA,yCAAU,EAAE,UAAU,eAAe,EAAE;yBACtD;oBACA;QACF;QAEA,MAAM,MAAM;YACV,OAAO,SAAS,KAAK;YACrB,UAAU;gBACR,SAAS;YACX;YACA,WAAW;gBACT,iBAAiB,SAAS,eAAe;YAC3C;YACA,GAAG,SAAS;YACZ,iBAAiB,SAAS,eAAe;QAC3C;QAEA,KAAK,IAAI,CAAC;QAEV,SAAS,GAAG,CAAC,UAAU,EAAE;IAC3B;IAEA,OAAO;AACT;AAEA,SAAS,+BAAS,GAAc,EAAE,aAAuB;IACvD,OAAO,cAAc,QAAQ,CAAC,IAAI,EAAE;AACtC;AAEA,SAAS,oCAAc,GAAc,EAAE,aAAuB;IAC5D,IAAI,cAAc,MAAM,KAAK,GAAG,OAAO;IACvC,OACE,AAAC,CAAA,cAAc,QAAQ,CAAC,IAAI,EAAE,KAC5B,IAAI,OAAO,EAAE,KAAK,CAAC,IAAM,cAAc,QAAQ,CAAC,GAAE,KACpD;AAEJ;AAEO,SAAS,0CAAa,KAAwB;IACnD,wBAAwB;IACxB,MAAM,QAAE,IAAI,iBAAE,aAAa,SAAE,KAAK,YAAE,QAAQ,gBAAE,YAAY,EAAE,GAAG;IAC/D,MAAM,UAA8B,gCAClC,CAAA,GAAA,yCAAc,EAAE,OAAO,OACvB;IAGF,OAAO,wBACL,6BACA;QACE,UAAU;QACV,WAAW,CAAC;YACV,IAAI,EAAE,GAAG,KAAK,aACZ,SAAS;gBACP,MAAM;gBACN,SAAS;oBAAE,KAAK;gBAAc;YAChC;QAEJ;IACF,GACA,wBAAE,2CAAiB;cACjB;iBACA;sBACA;kBACA;uBACA;IACF;AAEJ;AAEA,SAAS,6CAAuB,aAC9B,SAAS,EAGV;IACC,MAAM,YAAY,OAAO,YAAY;IACrC,IACE,CAAC,aACD,UAAU,WAAW,IACrB,UAAU,UAAU,KAAK,KACzB,CAAC,WAED,OAAO;IAET,MAAM,QAAQ,UAAU,UAAU,CAAC;IAEnC,IACE,CAAC,UAAU,QAAQ,CAAC,MAAM,cAAc,KACxC,CAAC,UAAU,QAAQ,CAAC,MAAM,YAAY,GAEtC,OAAO;IAGT,MAAM,WAAW,SAAS,WAAW;IACrC,SAAS,QAAQ,CAAC,WAAW;IAC7B,SAAS,MAAM,CAAC,MAAM,cAAc,EAAE,MAAM,WAAW;IACvD,MAAM,QAAQ,SAAS,QAAQ,GAAG,MAAM;IAExC,MAAM,eAAe,MAAM,QAAQ;IACnC,MAAM,MAAM,QAAQ,aAAa,MAAM;IAEvC,OAAO;eACL;aACA;QACA,MAAM;IACR;AACF;AAEA,SAAS,6BAAO,OAAE,GAAG,YAAE,QAAQ,QAAE,IAAI,WAAE,OAAO,gBAAE,YAAY,EAAE;IAC5D,IAAI,SAAE,KAAK,OAAE,GAAG,EAAE,GAAG;IACrB,eAAe;IACf,IAAI,IAAI,CAAC,MAAM,EAAE,IAAI,KAAK;QACxB,2EAA2E;QAC3E,MAAO,QAAQ,KAAK,KAAK,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,EAC3C;QAEF,MAAO,MAAM,KAAK,MAAM,IAAI,KAAK,IAAI,CAAC,IAAI,CAAC,IAAI,EAC7C;IAEJ;IAEA,IAAI,UAAU;eAAE;aAAO;QAAK,MAAM,KAAK,KAAK,CAAC,OAAO;IAAK;IAEzD,IAAI,QAAQ,IAAI,CAAC,IAAI,OAAO,IAAI;QAC9B,QAAQ,GAAG,CAAC;QACZ;IACF;IAEA,MAAM,YAAY,QAAQ,IAAI,CAC5B,CAAC,IACC,EAAE,KAAK,KAAK,QAAQ,KAAK,IACxB,CAAA,EAAE,GAAG,KAAK,QAAQ,GAAG,IAAI,EAAE,GAAG,KAAK,QAAQ,GAAG,GAAG,CAAA;IAGtD,IAAI,WAAW;QACb,QAAQ,GAAG,CAAC;QACZ;IACF;IAEA,IAAI,QAAQ,IAAI,CAAC,QAAQ,CAAC,MAAM;QAC9B,QAAQ,IAAI,GAAG,QAAQ,IAAI,CAAC,KAAK,CAAC,GAAG;QACrC,QAAQ,GAAG,IAAI;IACjB;IAEA,MAAM,SAAS,QAAQ,IAAI,CACzB,CAAC,IAAM,EAAE,KAAK,IAAI,QAAQ,KAAK,IAAI,EAAE,GAAG,IAAI,QAAQ,GAAG;IAGzD,MAAM,UAAU,QAAQ,IAAI,CAC1B,CAAC,IAAM,EAAE,KAAK,GAAG,QAAQ,GAAG,IAAI,EAAE,GAAG,GAAG,QAAQ,KAAK;IAGvD,IAAI,AAAC,CAAA,UAAU,OAAM,KAAM,CAAC,cAAc;QACxC,QAAQ,GAAG,CAAC;QACZ;IACF;IAEA,SAAS;QAAE,MAAM;iBAAe;IAAQ;AAC1C;AAEA,SAAS,qCAAe,IAAY,EAAE,IAAwB;IAC5D,MAAM,SAID,EAAE;IAEP,KAAK,MAAM,OAAO,KAAM;QACtB,OAAO,IAAI,CAAC;YAAE,KAAK,IAAI,KAAK;YAAE,MAAM;iBAAS;QAAI;QACjD,OAAO,IAAI,CAAC;YAAE,KAAK,IAAI,GAAG;YAAE,MAAM;iBAAO;QAAI;IAC/C;IAEA,OAAO,IAAI,CAAC,CAAC,GAAG;QACd,IAAI,EAAE,GAAG,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,GAAG,EAAE,GAAG;QACzC,IAAI,EAAE,IAAI,KAAK,SAAS,EAAE,IAAI,KAAK,SAAS,OAAO;QACnD,IAAI,EAAE,IAAI,KAAK,WAAW,EAAE,IAAI,KAAK,OAAO,OAAO;QACnD,OAAO;IACT;IAEA,MAAM,OAAO;QAAE,UAAU,EAAE;QAAE,WAAW;IAAE;IAC1C,MAAM,QAAQ;QAAC;KAAK;IACpB,IAAI,UAAU;IAEd,KAAK,MAAM,OAAE,GAAG,QAAE,IAAI,OAAE,GAAG,EAAE,IAAI,OAAQ;QACvC,MAAM,SAAS,KAAK,CAAC,MAAM,MAAM,GAAG,EAAE;QAEtC,IAAI,MAAM,SAAS;YACjB,MAAM,QAAQ,KAAK,KAAK,CAAC,SAAS;YAClC,OAAO,QAAQ,CAAC,IAAI,CAAC;QACvB;QAEA,IAAI,SAAS,SAAS;YACpB,MAAM,UAAU;qBAAE;gBAAK,UAAU,EAAE;gBAAE,WAAW;YAAI;YACpD,OAAO,QAAQ,CAAC,IAAI,CAAC;YACrB,MAAM,IAAI,CAAC;QACb,OACE,MAAM,GAAG;QAGX,UAAU;IACZ;IAEA,IAAI,UAAU,KAAK,MAAM,EACvB,KAAK,CAAC,MAAM,MAAM,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC;IAGnD,OAAO;AACT;AAEA,SAAS,iCACP,IAAS,EACT,QAAsB,EACtB,aAAuB,EACvB,cAAuB;IAEvB,IAAI,OAAO,SAAS,UAAU,OAAO;IAErC,MAAM,OAAE,GAAG,YAAE,QAAQ,EAAE,GAAG;IAC1B,MAAM,aAAa,eAAe,SAAS,IAAI,EAAE;IACjD,MAAM,aAAa,cAAc,MAAM,KAAK,KAAK;IAEjD,MAAM,QAAQ;QACZ,GAAG,GAAG;QACN,QAAQ,iBAAiB,KAAK;QAC9B,QAAQ,eAAgB,CAAA,aAAa,IAAI,KAAK,GAAG,aAAY;QAC7D,QAAQ;IACV;IAEA,IAAI,WAAW,EAAE;IACjB,IAAI,YAAY;QACd,IAAK,MAAM,OAAO,SAChB,IAAI,OAAO,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,UAAU,MAAM;YACvD,MAAM,QAAQ,QAAQ,CAAC,IAAI;YAC3B,IAAI,OAAO,KACT,SAAS,IAAI,CAAC,MAAM,QAAQ,CAAC,EAAE;iBAE/B,SAAS,IAAI,CAAC;QAElB;IAEJ;IAEA,OAAO,wBACL,QACA;QACE,WAAW;eACX;QACA,SAAS,CAAC;YACR,EAAE,eAAe;YACjB,IACE,EAAE,OAAO,IACT,EAAE,OAAO,IACR,aAAa,CAAC,EAAE,KAAK,IAAI,EAAE,IAAI,cAAc,MAAM,KAAK,GACzD;gBACA,wEAAwE;gBACxE,EAAE,eAAe;gBACjB,SAAS;oBACP,MAAM;oBACN,SAAS;wBAAE,KAAK;4BAAC,IAAI,EAAE;yBAAC;oBAAC;gBAC3B;YACF,OAAO,IAAI,EAAE,QAAQ,IAAI,cAAc,MAAM,GAAG,GAAG;gBACjD,mDAAmD;gBACnD,MAAM,eAAe,aAAa,CAAC,cAAc,MAAM,GAAG,EAAE;gBAE5D,SAAS;oBACP,MAAM;oBACN,SAAS;wBAAE,KAAK;4BAAC;4BAAc,IAAI,EAAE;yBAAC;oBAAC;gBACzC;YACF,OACE,SAAS;gBACP,MAAM;gBACN,SAAS;oBAAE,KAAK;wBAAC,IAAI,EAAE;qBAAC;gBAAC;YAC3B;QAEJ;IACF,GACA,aACI,SAAS,IAAI,KACb,SAAS,GAAG,CAAC,CAAC,OAAY,IACxB,iCAAW,OAAO,UAAU,eAAe;AAGrD;AAEO,SAAS,0CAAgB,KAO/B;IACC,MAAM,QAAE,IAAI,WAAE,UAAU,EAAE,YAAE,QAAQ,iBAAE,aAAa,gBAAE,YAAY,EAAE,GAAG;IAEtE,MAAM,OAAO,qCAAe,MAAM;IAElC,MAAM,UAAU,CAAA,GAAA,aAAK,EAAmB;IAExC,CAAA,GAAA,gBAAQ,EAAE;QACR,MAAM,gBAAgB;YACpB,MAAM,MAAM,6CAAuB;gBAAE,WAAW,QAAQ,OAAO;YAAC;YAChE,IAAI,CAAC,KAAK;YACV,6BAAO;qBAAE;0BAAK;sBAAU;yBAAM;8BAAS;YAAa;QACtD;QAEA,SAAS,gBAAgB,CAAC,WAAW;QACrC,OAAO;YACL,SAAS,mBAAmB,CAAC,WAAW;QAC1C;IACF,GAAG;QAAC;QAAM;QAAS;QAAU;KAAa;IAE1C,OAAO,wBACL,QACA;QAAE,KAAK;IAAQ,GACf,KAAK,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAY,IAC7B,iCAAW,OAAO,UAAU,eAAe;AAGjD","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
1
|
import {EntityTag as $03d8811e9c9b360d$export$117e56c71b172cde} from "./feedback-components.5df2a926.js";
|
|
2
|
-
import {useTreeDispatch as $b79bf29960412ca7$export$e1068f2d1c68f87e} from "./feedback-components.
|
|
3
|
-
import "./feedback-components.
|
|
4
|
-
import $gIldz$
|
|
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
|
|
@@ -61,4 +61,4 @@ var $b6b9741bf83336eb$export$2e2bcd8739ae039 = $b6b9741bf83336eb$var$Node;
|
|
|
61
61
|
|
|
62
62
|
|
|
63
63
|
export {$b6b9741bf83336eb$export$2e2bcd8739ae039 as default};
|
|
64
|
-
//# sourceMappingURL=feedback-components.
|
|
64
|
+
//# sourceMappingURL=feedback-components.5509fab3.js.map
|
package/dist/esm/{feedback-components.87533431.js.map → feedback-components.5509fab3.js.map}
RENAMED
|
@@ -1 +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.
|
|
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"}
|