@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.
Files changed (95) hide show
  1. package/PRODUCTION_ARCHITECTURE.md +511 -0
  2. package/README.md +379 -0
  3. package/SAVE_FUNCTIONALITY_COMPLETE.md +448 -0
  4. package/dist/cjs/EditableContent.js +150 -0
  5. package/dist/cjs/HtmlViewer.js +587 -0
  6. package/dist/cjs/PdfComponents.js +16 -0
  7. package/dist/cjs/PdfDocumentViewer.js +281 -0
  8. package/dist/cjs/Structura.js +806 -0
  9. package/dist/cjs/Table.js +164 -0
  10. package/dist/cjs/TableCell.js +115 -0
  11. package/dist/cjs/accuracyMetrics.js +39 -0
  12. package/dist/cjs/helpers/preprocessData.js +143 -0
  13. package/dist/cjs/index.js +7 -0
  14. package/dist/cjs/lib/polyfills.js +15 -0
  15. package/dist/cjs/lib/utils.js +10 -0
  16. package/dist/cjs/node_modules/react-icons/fa/index.esm.js +14 -0
  17. package/dist/cjs/node_modules/react-icons/lib/esm/iconBase.js +69 -0
  18. package/dist/cjs/node_modules/react-icons/lib/esm/iconContext.js +15 -0
  19. package/dist/cjs/polyfills.js +19 -0
  20. package/dist/cjs/route.js +102 -0
  21. package/dist/cjs/styles.css +7 -0
  22. package/dist/cjs/styles.css.map +1 -0
  23. package/dist/cjs/ui/badge.js +34 -0
  24. package/dist/cjs/ui/button.js +71 -0
  25. package/dist/cjs/ui/card.js +86 -0
  26. package/dist/cjs/ui/progress.js +45 -0
  27. package/dist/cjs/ui/scroll-area.js +62 -0
  28. package/dist/cjs/ui/tabs.js +60 -0
  29. package/dist/cjs/worker.js +36 -0
  30. package/dist/esm/EditableContent.js +161 -0
  31. package/dist/esm/HtmlViewer.js +640 -0
  32. package/dist/esm/PdfComponents.js +21 -0
  33. package/dist/esm/PdfDocumentViewer.js +294 -0
  34. package/dist/esm/Structura.js +951 -0
  35. package/dist/esm/Table.js +182 -0
  36. package/dist/esm/TableCell.js +122 -0
  37. package/dist/esm/_virtual/_rollupPluginBabelHelpers.js +305 -0
  38. package/dist/esm/accuracyMetrics.js +41 -0
  39. package/dist/esm/helpers/preprocessData.js +152 -0
  40. package/dist/esm/index.js +1 -0
  41. package/dist/esm/lib/polyfills.js +13 -0
  42. package/dist/esm/lib/utils.js +8 -0
  43. package/dist/esm/node_modules/react-icons/fa/index.esm.js +11 -0
  44. package/dist/esm/node_modules/react-icons/lib/esm/iconBase.js +66 -0
  45. package/dist/esm/node_modules/react-icons/lib/esm/iconContext.js +12 -0
  46. package/dist/esm/polyfills.js +17 -0
  47. package/dist/esm/route.js +154 -0
  48. package/dist/esm/styles.css +7 -0
  49. package/dist/esm/styles.css.map +1 -0
  50. package/dist/esm/types/EditableContent.d.ts +9 -0
  51. package/dist/esm/types/HtmlViewer.d.ts +10 -0
  52. package/dist/esm/types/PdfComponents.d.ts +35 -0
  53. package/dist/esm/types/PdfDocumentViewer.d.ts +22 -0
  54. package/dist/esm/types/Structura.d.ts +11 -0
  55. package/dist/esm/types/Table.d.ts +12 -0
  56. package/dist/esm/types/TableCell.d.ts +13 -0
  57. package/dist/esm/types/accuracy.d.ts +23 -0
  58. package/dist/esm/types/accuracyMetrics.d.ts +5 -0
  59. package/dist/esm/types/helpers/flattenJSON.d.ts +1 -0
  60. package/dist/esm/types/helpers/hardMerging.d.ts +2 -0
  61. package/dist/esm/types/helpers/index.d.ts +6 -0
  62. package/dist/esm/types/helpers/jsonToHtml.d.ts +40 -0
  63. package/dist/esm/types/helpers/preprocessData.d.ts +3 -0
  64. package/dist/esm/types/helpers/removeMetadata.d.ts +1 -0
  65. package/dist/esm/types/helpers/tableProcessor.d.ts +1 -0
  66. package/dist/esm/types/index.d.ts +3 -0
  67. package/dist/esm/types/lib/polyfills.d.ts +1 -0
  68. package/dist/esm/types/lib/utils.d.ts +2 -0
  69. package/dist/esm/types/polyfills.d.ts +1 -0
  70. package/dist/esm/types/route.d.ts +45 -0
  71. package/dist/esm/types/test-app/src/App.d.ts +4 -0
  72. package/dist/esm/types/test-app/src/main.d.ts +1 -0
  73. package/dist/esm/types/test-app/vite.config.d.ts +2 -0
  74. package/dist/esm/types/types.d.ts +23 -0
  75. package/dist/esm/types/ui/alert.d.ts +8 -0
  76. package/dist/esm/types/ui/badge.d.ts +9 -0
  77. package/dist/esm/types/ui/button.d.ts +11 -0
  78. package/dist/esm/types/ui/card.d.ts +8 -0
  79. package/dist/esm/types/ui/progress.d.ts +6 -0
  80. package/dist/esm/types/ui/scroll-area.d.ts +5 -0
  81. package/dist/esm/types/ui/skeleton.d.ts +2 -0
  82. package/dist/esm/types/ui/tabs.d.ts +7 -0
  83. package/dist/esm/types/worker.d.ts +1 -0
  84. package/dist/esm/ui/badge.js +31 -0
  85. package/dist/esm/ui/button.js +50 -0
  86. package/dist/esm/ui/card.js +67 -0
  87. package/dist/esm/ui/progress.js +26 -0
  88. package/dist/esm/ui/scroll-area.js +45 -0
  89. package/dist/esm/ui/tabs.js +39 -0
  90. package/dist/esm/worker.js +50 -0
  91. package/dist/index.d.ts +38 -0
  92. package/package.json +85 -0
  93. package/server/README.md +203 -0
  94. package/server/db.js +142 -0
  95. 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 };