@tfw.in/structura-lib 0.2.0
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/PRODUCTION_ARCHITECTURE.md +511 -0
- package/README.md +379 -0
- package/SAVE_FUNCTIONALITY_COMPLETE.md +448 -0
- package/dist/cjs/EditableContent.js +150 -0
- package/dist/cjs/HtmlViewer.js +587 -0
- package/dist/cjs/PdfComponents.js +16 -0
- package/dist/cjs/PdfDocumentViewer.js +281 -0
- package/dist/cjs/Structura.js +806 -0
- package/dist/cjs/Table.js +164 -0
- package/dist/cjs/TableCell.js +115 -0
- package/dist/cjs/accuracyMetrics.js +39 -0
- package/dist/cjs/helpers/preprocessData.js +143 -0
- package/dist/cjs/index.js +7 -0
- package/dist/cjs/lib/polyfills.js +15 -0
- package/dist/cjs/lib/utils.js +10 -0
- package/dist/cjs/node_modules/react-icons/fa/index.esm.js +14 -0
- package/dist/cjs/node_modules/react-icons/lib/esm/iconBase.js +69 -0
- package/dist/cjs/node_modules/react-icons/lib/esm/iconContext.js +15 -0
- package/dist/cjs/polyfills.js +19 -0
- package/dist/cjs/route.js +102 -0
- package/dist/cjs/styles.css +7 -0
- package/dist/cjs/styles.css.map +1 -0
- package/dist/cjs/ui/badge.js +34 -0
- package/dist/cjs/ui/button.js +71 -0
- package/dist/cjs/ui/card.js +86 -0
- package/dist/cjs/ui/progress.js +45 -0
- package/dist/cjs/ui/scroll-area.js +62 -0
- package/dist/cjs/ui/tabs.js +60 -0
- package/dist/cjs/worker.js +36 -0
- package/dist/esm/EditableContent.js +161 -0
- package/dist/esm/HtmlViewer.js +640 -0
- package/dist/esm/PdfComponents.js +21 -0
- package/dist/esm/PdfDocumentViewer.js +294 -0
- package/dist/esm/Structura.js +951 -0
- package/dist/esm/Table.js +182 -0
- package/dist/esm/TableCell.js +122 -0
- package/dist/esm/_virtual/_rollupPluginBabelHelpers.js +305 -0
- package/dist/esm/accuracyMetrics.js +41 -0
- package/dist/esm/helpers/preprocessData.js +152 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/lib/polyfills.js +13 -0
- package/dist/esm/lib/utils.js +8 -0
- package/dist/esm/node_modules/react-icons/fa/index.esm.js +11 -0
- package/dist/esm/node_modules/react-icons/lib/esm/iconBase.js +66 -0
- package/dist/esm/node_modules/react-icons/lib/esm/iconContext.js +12 -0
- package/dist/esm/polyfills.js +17 -0
- package/dist/esm/route.js +154 -0
- package/dist/esm/styles.css +7 -0
- package/dist/esm/styles.css.map +1 -0
- package/dist/esm/types/EditableContent.d.ts +9 -0
- package/dist/esm/types/HtmlViewer.d.ts +10 -0
- package/dist/esm/types/PdfComponents.d.ts +35 -0
- package/dist/esm/types/PdfDocumentViewer.d.ts +22 -0
- package/dist/esm/types/Structura.d.ts +11 -0
- package/dist/esm/types/Table.d.ts +12 -0
- package/dist/esm/types/TableCell.d.ts +13 -0
- package/dist/esm/types/accuracy.d.ts +23 -0
- package/dist/esm/types/accuracyMetrics.d.ts +5 -0
- package/dist/esm/types/helpers/flattenJSON.d.ts +1 -0
- package/dist/esm/types/helpers/hardMerging.d.ts +2 -0
- package/dist/esm/types/helpers/index.d.ts +6 -0
- package/dist/esm/types/helpers/jsonToHtml.d.ts +40 -0
- package/dist/esm/types/helpers/preprocessData.d.ts +3 -0
- package/dist/esm/types/helpers/removeMetadata.d.ts +1 -0
- package/dist/esm/types/helpers/tableProcessor.d.ts +1 -0
- package/dist/esm/types/index.d.ts +3 -0
- package/dist/esm/types/lib/polyfills.d.ts +1 -0
- package/dist/esm/types/lib/utils.d.ts +2 -0
- package/dist/esm/types/polyfills.d.ts +1 -0
- package/dist/esm/types/route.d.ts +45 -0
- package/dist/esm/types/test-app/src/App.d.ts +4 -0
- package/dist/esm/types/test-app/src/main.d.ts +1 -0
- package/dist/esm/types/test-app/vite.config.d.ts +2 -0
- package/dist/esm/types/types.d.ts +23 -0
- package/dist/esm/types/ui/alert.d.ts +8 -0
- package/dist/esm/types/ui/badge.d.ts +9 -0
- package/dist/esm/types/ui/button.d.ts +11 -0
- package/dist/esm/types/ui/card.d.ts +8 -0
- package/dist/esm/types/ui/progress.d.ts +6 -0
- package/dist/esm/types/ui/scroll-area.d.ts +5 -0
- package/dist/esm/types/ui/skeleton.d.ts +2 -0
- package/dist/esm/types/ui/tabs.d.ts +7 -0
- package/dist/esm/types/worker.d.ts +1 -0
- package/dist/esm/ui/badge.js +31 -0
- package/dist/esm/ui/button.js +50 -0
- package/dist/esm/ui/card.js +67 -0
- package/dist/esm/ui/progress.js +26 -0
- package/dist/esm/ui/scroll-area.js +45 -0
- package/dist/esm/ui/tabs.js +39 -0
- package/dist/esm/worker.js +50 -0
- package/dist/index.d.ts +38 -0
- package/package.json +85 -0
- package/server/README.md +203 -0
- package/server/db.js +142 -0
- package/server/server.js +165 -0
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { slicedToArray as _slicedToArray } from './_virtual/_rollupPluginBabelHelpers.js';
|
|
2
|
+
import { jsx } from 'react/jsx-runtime';
|
|
3
|
+
import { useState, useRef, useEffect } from 'react';
|
|
4
|
+
|
|
5
|
+
// Helper function to extract text content while preserving structure
|
|
6
|
+
var extractTextPreservingStructure = function extractTextPreservingStructure(html) {
|
|
7
|
+
var _a;
|
|
8
|
+
// Create a temporary DOM element
|
|
9
|
+
var tempDiv = document.createElement("div");
|
|
10
|
+
tempDiv.innerHTML = html;
|
|
11
|
+
// For headings, preserve the heading tag but extract just the text
|
|
12
|
+
if (html.match(/<h[1-6]/i)) {
|
|
13
|
+
((_a = html.match(/<(h[1-6])/i)) === null || _a === void 0 ? void 0 : _a[1]) || "p";
|
|
14
|
+
var textContent = tempDiv.textContent || tempDiv.innerText || "";
|
|
15
|
+
return textContent;
|
|
16
|
+
}
|
|
17
|
+
// For other elements, extract just the text content
|
|
18
|
+
return tempDiv.textContent || tempDiv.innerText || "";
|
|
19
|
+
};
|
|
20
|
+
function EditableContent(_ref) {
|
|
21
|
+
var id = _ref.id,
|
|
22
|
+
content = _ref.content,
|
|
23
|
+
onContentChange = _ref.onContentChange,
|
|
24
|
+
_ref$isHeading = _ref.isHeading,
|
|
25
|
+
isHeading = _ref$isHeading === void 0 ? false : _ref$isHeading,
|
|
26
|
+
onNodeClick = _ref.onNodeClick;
|
|
27
|
+
var _useState = useState(false),
|
|
28
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
29
|
+
isEditing = _useState2[0],
|
|
30
|
+
setIsEditing = _useState2[1];
|
|
31
|
+
var _useState3 = useState(content),
|
|
32
|
+
_useState4 = _slicedToArray(_useState3, 2),
|
|
33
|
+
editedContent = _useState4[0],
|
|
34
|
+
setEditedContent = _useState4[1];
|
|
35
|
+
var _useState5 = useState(""),
|
|
36
|
+
_useState6 = _slicedToArray(_useState5, 2),
|
|
37
|
+
textAreaContent = _useState6[0],
|
|
38
|
+
setTextAreaContent = _useState6[1];
|
|
39
|
+
var _useState7 = useState(false),
|
|
40
|
+
_useState8 = _slicedToArray(_useState7, 2),
|
|
41
|
+
isEdited = _useState8[0],
|
|
42
|
+
setIsEdited = _useState8[1];
|
|
43
|
+
var contentRef = useRef(null);
|
|
44
|
+
var originalHtmlStructure = useRef(content);
|
|
45
|
+
// Update content when props change, but preserve edited state
|
|
46
|
+
useEffect(function () {
|
|
47
|
+
if (!isEdited) {
|
|
48
|
+
setEditedContent(content);
|
|
49
|
+
originalHtmlStructure.current = content;
|
|
50
|
+
}
|
|
51
|
+
}, [content, isEdited]);
|
|
52
|
+
// Extract heading level if content is a heading
|
|
53
|
+
var headingLevel = 1;
|
|
54
|
+
var originalTag = "p";
|
|
55
|
+
if (isHeading) {
|
|
56
|
+
var headingMatch = content.match(/<h([1-6])/);
|
|
57
|
+
headingLevel = headingMatch ? parseInt(headingMatch[1]) : 1;
|
|
58
|
+
originalTag = "h".concat(headingLevel);
|
|
59
|
+
} else {
|
|
60
|
+
// Try to detect paragraph or other tags
|
|
61
|
+
var tagMatch = content.match(/<([a-z0-9]+)[^>]*>/i);
|
|
62
|
+
originalTag = tagMatch ? tagMatch[1] : "p";
|
|
63
|
+
}
|
|
64
|
+
var getHeadingStyles = function getHeadingStyles(level) {
|
|
65
|
+
switch (level) {
|
|
66
|
+
case 1:
|
|
67
|
+
return "text-2xl font-bold";
|
|
68
|
+
case 2:
|
|
69
|
+
return "text-xl font-bold";
|
|
70
|
+
case 3:
|
|
71
|
+
return "text-lg font-bold";
|
|
72
|
+
case 4:
|
|
73
|
+
return "text-base font-bold";
|
|
74
|
+
case 5:
|
|
75
|
+
return "text-sm font-bold";
|
|
76
|
+
case 6:
|
|
77
|
+
return "text-xs font-bold";
|
|
78
|
+
default:
|
|
79
|
+
return "text-base";
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
var handleDoubleClick = function handleDoubleClick(e) {
|
|
83
|
+
// Stop propagation to prevent parent click handlers from firing
|
|
84
|
+
e.stopPropagation();
|
|
85
|
+
if (onContentChange) {
|
|
86
|
+
// Extract text content for textarea while preserving structure
|
|
87
|
+
setTextAreaContent(extractTextPreservingStructure(editedContent));
|
|
88
|
+
setIsEditing(true);
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
var handleChange = function handleChange(e) {
|
|
92
|
+
setTextAreaContent(e.target.value);
|
|
93
|
+
};
|
|
94
|
+
var handleBlur = function handleBlur() {
|
|
95
|
+
setIsEditing(false);
|
|
96
|
+
// Only update if content actually changed
|
|
97
|
+
// Preserve original HTML structure (tag) but update the content
|
|
98
|
+
var newHtmlContent = "";
|
|
99
|
+
if (isHeading || originalTag.match(/^h[1-6]$/)) {
|
|
100
|
+
// For headings
|
|
101
|
+
newHtmlContent = "<".concat(originalTag, ">").concat(textAreaContent, "</").concat(originalTag, ">");
|
|
102
|
+
} else if (originalTag === "p" || !originalHtmlStructure.current.match(/<[a-z]+[^>]*>/i)) {
|
|
103
|
+
// For paragraphs or plain text
|
|
104
|
+
newHtmlContent = "<p>".concat(textAreaContent, "</p>");
|
|
105
|
+
} else {
|
|
106
|
+
// For other elements, try to preserve the original tag
|
|
107
|
+
newHtmlContent = "<".concat(originalTag, ">").concat(textAreaContent, "</").concat(originalTag, ">");
|
|
108
|
+
}
|
|
109
|
+
// Compare original text content with new text content for change detection
|
|
110
|
+
var originalTextContent = extractTextPreservingStructure(content);
|
|
111
|
+
if (textAreaContent !== originalTextContent && onContentChange) {
|
|
112
|
+
setEditedContent(newHtmlContent);
|
|
113
|
+
setIsEdited(true);
|
|
114
|
+
onContentChange(id, newHtmlContent);
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
var handleClick = function handleClick(e) {
|
|
118
|
+
// Stop editing mode click from propagating
|
|
119
|
+
if (isEditing) {
|
|
120
|
+
e.stopPropagation();
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
// If there's an onNodeClick handler, call it
|
|
124
|
+
if (onNodeClick) {
|
|
125
|
+
e.stopPropagation(); // Prevent click from reaching parent containers
|
|
126
|
+
onNodeClick();
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
var handleKeyDown = function handleKeyDown(e) {
|
|
130
|
+
// Handle Enter key to complete editing (Shift+Enter to add a line break)
|
|
131
|
+
if (e.key === "Enter" && !e.shiftKey) {
|
|
132
|
+
e.preventDefault();
|
|
133
|
+
handleBlur();
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
return jsx("div", {
|
|
137
|
+
className: "w-full ".concat(isEdited ? "bg-yellow-100" : "", " ").concat(onNodeClick && !isEditing ? "cursor-pointer" : ""),
|
|
138
|
+
onClick: handleClick,
|
|
139
|
+
onDoubleClick: handleDoubleClick,
|
|
140
|
+
children: isEditing ? jsx("textarea", {
|
|
141
|
+
value: textAreaContent,
|
|
142
|
+
onChange: handleChange,
|
|
143
|
+
onBlur: handleBlur,
|
|
144
|
+
onKeyDown: handleKeyDown,
|
|
145
|
+
autoFocus: true,
|
|
146
|
+
className: "w-full p-1 border border-blue-400 rounded focus:outline-none focus:ring-2 focus:ring-blue-500 bg-white text-gray-900",
|
|
147
|
+
onClick: function onClick(e) {
|
|
148
|
+
return e.stopPropagation();
|
|
149
|
+
},
|
|
150
|
+
rows: 3
|
|
151
|
+
}) : jsx("div", {
|
|
152
|
+
ref: contentRef,
|
|
153
|
+
className: "prose max-w-none ".concat(isHeading ? getHeadingStyles(headingLevel) : ""),
|
|
154
|
+
dangerouslySetInnerHTML: {
|
|
155
|
+
__html: editedContent
|
|
156
|
+
}
|
|
157
|
+
})
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
export { EditableContent as default };
|